Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 9x 9x 9x 9x 1x 8x 8x 1x 7x 7x 7x 1x | import { SKIP_ERROR_NOTIFICATION, CUSTOM_ERROR_MESSAGE, SKIP_ERROR_FOR_STATUSES } from './http-context-tokens';
import { HttpErrorMapperService } from './http-error-mapper.service';
import { NotificationService } from '../services/notification.service';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
HttpErrorResponse,
HTTP_INTERCEPTORS,
} from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
/**
* HTTP interceptor that automatically shows toast notifications for HTTP errors.
*
* Behavior can be controlled per-request using HTTP context tokens:
*
* @example
* // Skip error notification entirely
* this.http.get('/api/data', {
* context: new HttpContext().set(SKIP_ERROR_NOTIFICATION, true)
* });
*
* @example
* // Skip only for specific status codes
* this.http.get('/api/data', {
* context: new HttpContext().set(SKIP_ERROR_FOR_STATUSES, [404])
* });
*
* @example
* // Custom error message
* this.http.post('/api/action', body, {
* context: new HttpContext().set(CUSTOM_ERROR_MESSAGE, 'Failed to save')
* });
*/
@Injectable()
export class ErrorNotificationInterceptor implements HttpInterceptor {
private readonly notification = inject(NotificationService);
private readonly errorMapper = inject(HttpErrorMapperService);
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(request).pipe(
catchError((error: unknown) => {
if (error instanceof HttpErrorResponse) {
this.handleError(request, error);
} else E{
this.notification.error('Произошла неожиданная ошибка.');
}
return throwError(() => error);
})
);
}
private handleError(request: HttpRequest<unknown>, error: HttpErrorResponse): void {
// Check if notifications are completely skipped for this request
if (request.context.get(SKIP_ERROR_NOTIFICATION)) {
return;
}
// Check if this specific status code should be skipped
const skipStatuses = request.context.get(SKIP_ERROR_FOR_STATUSES);
if (skipStatuses.length > 0 && skipStatuses.includes(error.status)) {
return;
}
// Determine the message to show
const customMessage = request.context.get(CUSTOM_ERROR_MESSAGE);
const message = customMessage || this.errorMapper.mapError(error).message;
this.notification.error(message);
}
}
/**
* Provider for ErrorNotificationInterceptor.
* Add this to your app providers to enable automatic error notifications.
*
* @example
* // app.config.ts
* export const appConfig: ApplicationConfig = {
* providers: [
* provideHttpClient(withInterceptorsFromDi()),
* errorNotificationInterceptorProvider,
* ],
* };
*/
export const errorNotificationInterceptorProvider = {
provide: HTTP_INTERCEPTORS,
useClass: ErrorNotificationInterceptor,
multi: true,
};
|