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.
- 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
Install the core package via npm:
npm install @anglr/error-handling --saveThe 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
# 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 --saveThe 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 |
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,
]),
],
};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,
},
],
};AnglrExceptionHandler replaces Angular's default ErrorHandler and provides enhanced unhandled error handling including source map resolution, notifications, and extensibility through extenders.
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),
},
],
};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) |
- 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
All interceptors are available both as functional interceptors (recommended) and as class-based providers (deprecated).
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.'
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.'
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.'
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,
])),
],
};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}),
);
}
}// With custom options
processHttpClientErrorResponse(
{
injector: angularInjector,
ignoredHttpStatusCodes: [401, 403, 409],
clientErrorsResponseMapper: err => [err?.error?.message ?? 'Unknown error'],
clientValidationErrorsResponseMapper: err => err?.error?.validationErrors ?? null,
});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});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',
},
},
});Using custom error handler for specified status code.
catchHttpClientError(
{
handlers:
{
404: async (error: HttpClientError) =>
{
console.log('Custom 404 handler', error.response.url);
return null;
},
},
});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 |
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
}
}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.
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.
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 enrich error objects with additional context before they are logged. They implement the AnglrExceptionExtender type:
type AnglrExceptionExtender = (injector: Injector, error: ErrorWithStack) => Promise<ErrorWithStack>;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,
]),
],
};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,
]);| 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 |
| 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 |
Integration with @anglr/rest library, providing decorators and middlewares for declarative REST client error handling.
CatchHttpClientErrorMiddleware— wraps REST method responses withcatchHttpClientErroroperatorHttpClientErrorProcessingMiddleware— wraps REST method responses withprocessHttpClientErrorResponseoperator
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
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 |
Provides Angular Material–based renderer for internal server errors using MatDialog.
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.
Provides an exception extender that captures a screenshot of the current application state when an error occurs (browser only).
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.
| 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 |
| 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 |
| 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 |
| 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> |