@anglr/error-handling
v16.0.2
Published
Angular module used for handling http api error handling
Readme
@anglr/error-handling
Comprehensive Angular library for HTTP error handling, providing a unified approach to managing client errors (4xx), server errors (5xx), connection issues, and form validation errors in Angular applications. The library integrates with Angular's dependency injection, HTTP interceptors, RxJS operators, and reactive forms to deliver a complete error-handling solution.
Table of contents
- Installation
- Packages
- Getting started
- Global exception handler
- HTTP interceptors
- RxJS operators
- Server validation
- Internal server error display
- Exception extenders
- Injection tokens
- Provider functions
- Sub-packages
- API reference
- License
Installation
Install the core package via npm:
npm install @anglr/error-handling --savePeer dependencies
The library requires the following peer dependencies:
@angular/core>= 20.3.2@angular/common>= 20.3.2@angular/forms>= 20.3.2@angular/platform-browser>= 20.3.2@anglr/common>= 23.0.0@jscrpt/common>= 7.0.0rxjs>= 7.5.7
Optional sub-packages
# Angular Material dialog renderer for internal server errors
npm install @angular/material @angular/cdk --save
# Screenshot capture on error (browser only)
npm install html2canvas --save
# Integration with @anglr/rest
npm install @anglr/rest --savePackages
The library is organized into multiple entry points:
| Entry point | Description |
|---|---|
| @anglr/error-handling | Core error handling (interceptors, operators, services, components) |
| @anglr/error-handling/rest | @anglr/rest integration (decorators and middlewares) |
| @anglr/error-handling/material | Angular Material dialog renderer for internal server errors |
| @anglr/error-handling/html2canvas | Screenshot capture extender using html2canvas |
Getting started
Basic setup
Configure global error handling in your application configuration:
import {ApplicationConfig} from '@angular/core';
import {provideHttpClient, withInterceptors} from '@angular/common/http';
import {ANGLR_EXCEPTION_HANDLER_PROVIDER, httpServerErrorInterceptor, noConnectionInterceptor, serviceUnavailableInterceptor, httpGatewayTimeoutInterceptor, provideAnglrExceptionExtenders, errorWithUrlExtender} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
ANGLR_EXCEPTION_HANDLER_PROVIDER,
provideHttpClient(withInterceptors(
[
noConnectionInterceptor,
serviceUnavailableInterceptor,
httpGatewayTimeoutInterceptor,
httpServerErrorInterceptor,
])),
provideAnglrExceptionExtenders(
[
errorWithUrlExtender,
]),
],
};Providing notifications
The library uses injection tokens for notification services. You need to provide your own Notifications implementation from @anglr/common:
import {ApplicationConfig} from '@angular/core';
import {ERROR_HANDLING_NOTIFICATIONS, CLIENT_ERROR_NOTIFICATIONS} from '@anglr/error-handling';
import {NOTIFICATIONS} from '@anglr/common';
export const appConfig: ApplicationConfig =
{
providers:
[
{
provide: ERROR_HANDLING_NOTIFICATIONS,
useExisting: NOTIFICATIONS,
},
{
provide: CLIENT_ERROR_NOTIFICATIONS,
useExisting: NOTIFICATIONS,
},
],
};Global exception handler
AnglrExceptionHandler replaces Angular's default ErrorHandler and provides enhanced unhandled error handling including source map resolution, notifications, and extensibility through extenders.
Registration
import {ApplicationConfig, ValueProvider} from '@angular/core';
import {ANGLR_EXCEPTION_HANDLER_PROVIDER, AnglrExceptionHandlerOptions} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
ANGLR_EXCEPTION_HANDLER_PROVIDER,
//either use value provider or factory provider which benefits of using DI
<ValueProvider>
{
provide: AnglrExceptionHandlerOptions,
useValue: new AnglrExceptionHandlerOptions(true, false),
},
],
};Options
The AnglrExceptionHandlerOptions class accepts:
| Parameter | Type | Default | Description |
|---|---|---|---|
| debugMode | boolean | false | Logs errors to browser console with full stack traces |
| showAlsoAlert | boolean | false | Shows browser alert() with error message (debug only) |
How it works
- Captures unhandled errors via Angular's
ErrorHandlerinterface - Resolves source-mapped stack traces (browser only, via
sourcemapped-stacktrace) - Sends error notifications through
ERROR_HANDLING_NOTIFICATIONS - Runs all registered
AnglrExceptionExtenderfunctions to enrich the error - Logs the enriched error via
LOGGERfrom@anglr/common
HTTP interceptors
All interceptors are available both as functional interceptors (recommended) and as class-based providers (deprecated).
noConnectionInterceptor
Handles HTTP responses with status 0 (server offline / no connection).
import {ApplicationConfig, ValueProvider, provideHttpClient, withInterceptors} from '@angular/common/http';
import {noConnectionInterceptor, NoConnectionInterceptorOptions} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideHttpClient(withInterceptors(
[
noConnectionInterceptor,
])),
//either use value provider or factory provider which benefits of using DI
<ValueProvider>
{
provide: NoConnectionInterceptorOptions,
useValue: new NoConnectionInterceptorOptions('Custom offline message.'),
},
],
};Default message: 'Server is offline. Try again later.'
serviceUnavailableInterceptor
Handles HTTP 503 Service Unavailable responses.
import {ApplicationConfig, ValueProvider, provideHttpClient, withInterceptors} from '@angular/common/http';
import {serviceUnavailableInterceptor, ServiceUnavailableInterceptorOptions} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideHttpClient(withInterceptors(
[
serviceUnavailableInterceptor,
])),
//either use value provider or factory provider which benefits of using DI
<ValueProvider>
{
provide: ServiceUnavailableInterceptorOptions,
useValue: new ServiceUnavailableInterceptorOptions('Service is temporarily unavailable.'),
},
],
};Default message: 'Remote server is unavailable. Try again later.'
httpGatewayTimeoutInterceptor
Handles HTTP 504 Gateway Timeout responses.
import {ApplicationConfig, ValueProvider, provideHttpClient, withInterceptors} from '@angular/common/http';
import {httpGatewayTimeoutInterceptor, HttpGatewayTimeoutInterceptorOptions} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideHttpClient(withInterceptors(
[
httpGatewayTimeoutInterceptor,
])),
//either use value provider or factory provider which benefits of using DI
<ValueProvider>
{
provide: HttpGatewayTimeoutInterceptorOptions,
useValue: new HttpGatewayTimeoutInterceptorOptions('Gateway timeout occurred.'),
},
],
};Default message: 'Server did not respond in defined time.'
httpServerErrorInterceptor
Handles HTTP 5xx server errors. In dev mode (jsDevMode), logs errors and optionally renders error details through InternalServerErrorService.
import {ApplicationConfig, provideHttpClient, withInterceptors} from '@angular/common/http';
import {httpServerErrorInterceptor} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideHttpClient(withInterceptors(
[
httpServerErrorInterceptor,
])),
],
};RxJS operators
processHttpClientErrorResponse
Converts HttpErrorResponse with status codes 400..499 into HttpClientError objects. Non-HTTP errors and client-side errors are re-thrown unchanged.
import {inject, Injector} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {processHttpClientErrorResponse, catchHttpClientError} from '@anglr/error-handling';
@Injectable({providedIn: 'root'})
export class UserService
{
private _httpClient: HttpClient = inject(HttpClient);
private _injector: Injector = inject(Injector);
public getUser(id: number)
{
return this._httpClient.get(`/api/users/${id}`)
.pipe(
processHttpClientErrorResponse({injector: this._injector}),
catchHttpClientError({injector: this._injector}),
);
}
}Options
// With custom options
processHttpClientErrorResponse(
{
injector: angularInjector,
ignoredHttpStatusCodes: [401, 403, 409],
clientErrorsResponseMapper: err => [err?.error?.message ?? 'Unknown error'],
clientValidationErrorsResponseMapper: err => err?.error?.validationErrors ?? null,
});catchHttpClientError
Catches HttpClientError objects (produced by processHttpClientErrorResponse) and handles them according to provided options — displaying notifications, storing validation errors, and applying behavior.
// Suppress errors (default) — observable never completes on error
catchHttpClientError({injector: angularInjector});
// Pass through — HttpClientError is emitted as next value
catchHttpClientError({injector: angularInjector, behavior: CatchHttpClientErrorBehavior.PassThrogh});
// Throw — HttpClientError is re-thrown as observable error
catchHttpClientError({injector: angularInjector, behavior: CatchHttpClientErrorBehavior.Throw});Per-status-code configuration
Using default error handlers with custom configuration for different status codes.
catchHttpClientError(
{
configs:
{
404:
{
behavior: CatchHttpClientErrorBehavior.Throw,
message: 'Resource not found',
skipErrorNotifications: false,
skipServerValidationErrors: true,
forceCustomMessageDisplay: true,
},
409:
{
behavior: CatchHttpClientErrorBehavior.PassThrogh,
message: 'Conflict occurred',
},
},
});Custom error handlers
Using custom error handler for specified status code.
catchHttpClientError(
{
handlers:
{
404: async (error: HttpClientError) =>
{
console.log('Custom 404 handler', error.response.url);
return null;
},
},
});CatchHttpClientErrorBehavior
Enum controlling what happens after an HTTP client error is processed:
| Value | Description |
|---|---|
| Suppress | Error is handled silently, observable never completes (default) |
| PassThrogh | HttpClientError is emitted as the next observable value |
| Throw | HttpClientError is re-thrown as an observable error |
Server validation
ServerValidationService
Root-provided service for managing server-side validation errors. It stores validation errors received from HTTP responses and notifies subscribers when they change.
import {inject} from '@angular/core';
import {ServerValidationService} from '@anglr/error-handling';
@Injectable({providedIn: 'root'})
export class MyFormService
{
private _serverValidation: ServerValidationService = inject(ServerValidationService);
public submitForm(data: unknown)
{
// Clear previous validation errors before submission
this._serverValidation.clearServerValidationErrors();
// ... perform HTTP request
}
}ServerValidationValidatorDirective
Directive that integrates server-side validation errors with Angular reactive forms. Apply the serverValidation attribute to form controls to automatically display server validation errors.
<form>
<input formControlName="email"
serverValidation />
<input [formControl]="username"
serverValidation="userName" />
</form>- When
formControlNameis available value is used for obtaining name of validation property - If no
formControlNameis available, you have to specify validation property name usingserverValidation
The directive automatically revalidates the form control when server validation errors change.
Internal server error display
InternalServerErrorComponent
Component that subscribes to InternalServerErrorService and collects internal server error reports for display.
<internal-server-error />Place this component in your root application template. It listens for 5xx error events (triggered by httpServerErrorInterceptor) and renders them using the configured InternalServerErrorRenderer.
InternalServerErrorRenderer
Interface for customizing how internal server errors are displayed:
import {InternalServerErrorInfo, InternalServerErrorRenderer} from '@anglr/error-handling';
export class CustomErrorRenderer implements InternalServerErrorRenderer
{
public show(errorInfo: InternalServerErrorInfo, deleteCallback: (errorInfo: InternalServerErrorInfo) => void): void
{
// Custom rendering logic
console.log('Server error:', errorInfo.errorHtml, errorInfo.requestUrl);
deleteCallback(errorInfo);
}
}Register using the provider function:
import {ApplicationConfig} from '@angular/core';
import {provideInternalServerErrorRenderer} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideInternalServerErrorRenderer(CustomErrorRenderer),
],
};Exception extenders
Exception extenders enrich error objects with additional context before they are logged. They implement the AnglrExceptionExtender type:
type AnglrExceptionExtender = (injector: Injector, error: ErrorWithStack) => Promise<ErrorWithStack>;Built-in extenders
errorWithUrlExtender
Adds the current application URL (via Angular's Location service) to the error object.
import {provideAnglrExceptionExtenders, errorWithUrlExtender} from '@anglr/error-handling';
export const appConfig: ApplicationConfig =
{
providers:
[
provideAnglrExceptionExtenders(
[
errorWithUrlExtender,
]),
],
};Custom extenders
import {Injector} from '@angular/core';
import {AnglrExceptionExtender, ErrorWithStack} from '@anglr/error-handling';
export const errorWithTimestampExtender: AnglrExceptionExtender = (injector: Injector, error: ErrorWithStack): Promise<ErrorWithStack> =>
{
const extended = error as ErrorWithStack & {timestamp: string};
extended.timestamp = new Date().toISOString();
return Promise.resolve(extended);
};
// Register
provideAnglrExceptionExtenders(
[
errorWithUrlExtender,
errorWithTimestampExtender,
]);Injection tokens
| Token | Type | Default | Description |
|---|---|---|---|
| ERROR_HANDLING_NOTIFICATIONS | Notifications | — | Notifications service for error handling package |
| CLIENT_ERROR_NOTIFICATIONS | Notifications | — | Notifications service for HTTP client error display |
| HTTP_CLIENT_ERROR_RESPONSE_MAPPER | HttpClientErrorResponseMapper | err => [err?.error?.toString()] | Maps HttpErrorResponse to error messages |
| HTTP_CLIENT_VALIDATION_ERROR_RESPONSE_MAPPER | HttpClientValidationErrorResponseMapper | — | Maps HttpErrorResponse to validation errors |
| ANGLR_EXCEPTION_EXTENDERS | AnglrExceptionExtender[] | [] | Multi-token for exception extender functions |
| INTERNAL_SERVER_ERROR_RENDERER | InternalServerErrorRenderer | DummyInternalServerErrorRenderer | Renderer for internal server error display |
| HTTP_IGNORED_CLIENT_ERRORS | number[] | [401, 403] | HTTP status codes ignored by error processing |
| HTTP_CLIENT_ERROR_CONFIGS | HttpClientErrorConfigs | — | Per-status-code configuration for error handling |
| HTTP_CLIENT_ERROR_HANDLERS | HttpClientErrorHandlers | — | Per-status-code custom error handlers |
Provider functions
| Function | Description |
|---|---|
| provideAnglrExceptionExtenders(extenders) | Registers exception extender functions |
| provideInternalServerErrorRenderer(renderer) | Registers custom internal server error renderer |
| provideHttpClientErrorConfigs(configs) | Provides and merges per-status error configs |
| provideHttpClientErrorHandlers(handlers) | Provides and merges per-status error handlers |
| provideHttpClientErrorResponseMapper(mapper) | Provides custom error response mapper |
| provideHttpClientValidationErrorResponseMapper(mapper) | Provides custom validation error response mapper |
Sub-packages
@anglr/error-handling/rest
Integration with @anglr/rest library, providing decorators and middlewares for declarative REST client error handling.
Middlewares
CatchHttpClientErrorMiddleware— wraps REST method responses withcatchHttpClientErroroperatorHttpClientErrorProcessingMiddleware— wraps REST method responses withprocessHttpClientErrorResponseoperator
Injection tokens
ERROR_HANDLING_REST_MIDDLEWARES_ORDER- definition of array of rest middlewares order including error handling middlewareREST_ERROR_HANDLING_MIDDLEWARE_ORDER- provider for rest middleware order with error handling middleware
Decorators
All decorators modify REST method descriptors and are used on @anglr/rest service methods:
import {RESTClient, GET, BaseUrl} from '@anglr/rest';
import {HttpClientErrorBehavior, HttpClientErrorMessages, HttpClientErrorSkipErrorNotifications, IgnoredHttpErrorStatusCodes} from '@anglr/error-handling/rest';
import {CatchHttpClientErrorBehavior} from '@anglr/error-handling';
import {NEVER} from 'rxjs';
@Injectable({providedIn: 'root'})
@BaseUrl('/api')
export class UsersRestService extends RESTClient
{
@GET('/users/{id}')
@HttpClientErrorBehavior(CatchHttpClientErrorBehavior.Throw)
@HttpClientErrorMessages({404: 'User not found'})
public getUser(@Path('id') id: number): Observable<User>
{
return NEVER;
}
@GET('/users')
@HttpClientErrorBehavior(CatchHttpClientErrorBehavior.Suppress, 404)
@HttpClientErrorSkipErrorNotifications()
@IgnoredHttpErrorStatusCodes([409])
public getUsers(): Observable<User[]>
{
return NEVER;
}
}| Decorator | Description |
|---|---|
| @HttpClientErrorBehavior(behavior, statusCode?) | Sets error behavior globally or per status code |
| @HttpClientErrorMessages(messages) | Sets custom error messages per status code |
| @HttpClientErrorHandlers(handlers) | Sets custom error handlers per status code |
| @HttpClientErrorForceCustomMessage(indication?, statusCode?) | Forces custom message display |
| @HttpClientErrorSkipErrorNotifications(indication?, statusCode?) | Skips error notification display |
| @HttpClientErrorSkipServerValidationErrors(indication?, statusCode?) | Skips server validation error processing |
| @HttpClientErrorsMapper(mapper) | Sets custom error response mapper |
| @HttpClientValidationErrorsMapper(mapper) | Sets custom validation error response mapper |
| @IgnoredHttpErrorStatusCodes(statusCodes) | Sets ignored HTTP status codes |
@anglr/error-handling/material
Provides Angular Material–based renderer for internal server errors using MatDialog.
Setup
import {provideInternalServerErrorRenderer} from '@anglr/error-handling';
import {DialogInternalServerErrorRenderer} from '@anglr/error-handling/material';
export const appConfig: ApplicationConfig =
{
providers:
[
provideInternalServerErrorRenderer(DialogInternalServerErrorRenderer),
],
};The DialogInternalServerErrorRenderer opens a MatDialog at 90vw × 90vh displaying the full server error response HTML.
@anglr/error-handling/html2canvas
Provides an exception extender that captures a screenshot of the current application state when an error occurs (browser only).
Setup
import {provideAnglrExceptionExtenders, errorWithUrlExtender} from '@anglr/error-handling';
import {errorWithScreenShotExtender} from '@anglr/error-handling/html2canvas';
export const appConfig: ApplicationConfig =
{
providers:
[
provideAnglrExceptionExtenders(
[
errorWithUrlExtender,
errorWithScreenShotExtender,
]),
],
};The errorWithScreenShotExtender uses html2canvas to render document.body as a PNG and attaches the base64-encoded image to the error object as screenshotBase64.
API reference
Classes
| Class | Description |
|---|---|
| HttpClientError | Normalized wrapper for HTTP 4xx errors with errors, validationErrors, statusCode, message, response |
| HttpNotFoundError | Specialized HttpClientError for HTTP 404 responses |
| InternalServerErrorInfo | Model for internal server error display with id, errorHtml, requestUrl |
| AnglrExceptionHandlerOptions | Configuration options for the global exception handler |
| NoConnectionInterceptorOptions | Configuration for noConnectionInterceptor |
| ServiceUnavailableInterceptorOptions | Configuration for serviceUnavailableInterceptor |
| HttpGatewayTimeoutInterceptorOptions | Configuration for httpGatewayTimeoutInterceptor |
Services
| Service | Provided in | Description |
|---|---|---|
| AnglrExceptionHandler | via ANGLR_EXCEPTION_HANDLER_PROVIDER | Global exception handler with source map support |
| InternalServerErrorService | root | Emits internal server error events for display |
| ServerValidationService | root | Manages server-side validation errors |
| DummyInternalServerErrorRenderer | root (default) | No-op fallback renderer for internal server errors |
Interfaces
| Interface | Description |
|---|---|
| AnglrExceptionExtender | Async function signature for extending error objects |
| AngularError | Angular error shape with optional promise and rejection |
| CatchHttpClientErrorOptions | Options for catchHttpClientError operator |
| CatchHttpClientErrorHttpStatusCodeOptions | Per-status-code config (behavior, message, notification/validation skipping) |
| ErrorWithStack | Error with optional stack property |
| ErrorWithUrl | Extends error with optional applicationUrl |
| HttpClientErrorHandler | Async handler returning processed error or null |
| HttpClientErrorOptions | Options for processHttpClientErrorResponse operator |
| HttpClientErrors | Combined {errors, validationErrors} result |
| HttpClientPropertyValidationError | Map of validation error keys to messages |
| HttpClientValidationErrors | Property name to validation error map |
| InternalServerErrorRenderer | Contract for rendering internal server errors |
Types
| Type | Description |
|---|---|
| HttpClientErrorResponseMapper | (err: HttpErrorResponse) => PromiseOr<string[]> |
| HttpClientValidationErrorResponseMapper | (err: HttpErrorResponse) => PromiseOr<HttpClientValidationErrors\|null> |
| HttpClientErrorMessages | Record<number, string\|undefined\|null> |
| HttpClientErrorConfigs | Record<number, CatchHttpClientErrorHttpStatusCodeOptions\|undefined\|null> |
| HttpClientErrorHandlers | Record<number, HttpClientErrorHandler<HttpClientError>\|undefined\|null> |
