> home / blog /

Bypass Interceptors with HTTP_CONTEXT_TOKEN

June 24, 2024|angulartypescript

In many angular applications, you will find a global HTTP interceptor for error handling. It will mostly look something like this:

1@Injectable()
2export class GlobalErrorInterceptor implements HttpInterceptor {
3
4    intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
5        return next.handle(request).pipe(this.handleError(request));
6    }
7
8    private handleError(request: HttpRequest<any>) {
9        return <T>(source: Observable<T>) =>
10            source.pipe(
11                catchError((error: HttpErrorResponse) => {
12                    
13										// Some way of handling the error globally
14										// e.g. showing an error modal
15
16                    return throwError(() => error);
17                }),
18            );
19    }
20}

This will work great for cases where you want to have the same error handling every time. But sometimes you might want to have individual error handling for specific error codes.

A great way to achieve this is to use angular context tokens. You simply create a context token like this:

1export const BYPASS_ERROR_HANDLING_FOR_STATUS_CODES = new HttpContextToken(() => [] as number[]);

And then update your interceptor similar to this:

1@Injectable()
2export class GlobalErrorInterceptor implements HttpInterceptor {
3
4    intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
5        return next.handle(request).pipe(this.handleError(request));
6    }
7
8    private handleError(request: HttpRequest<any>) {
9        return <T>(source: Observable<T>) =>
10            source.pipe(
11                catchError((error: HttpErrorResponse) => {
12										const excludedStatusCodes = request.context.get(BYPASS_ERROR_HANDLING_FOR_STATUS_CODES) || [];
13
14										// Only do your global error handling if the status code is not excluded
15										if (!excludedStatusCodes.includes(error.status)) {
16											// Some way of handling the error globally
17											// e.g. showing an error modal
18										}
19
20                    return throwError(() => error);
21                }),
22            );
23    }
24}

This will allow you to use the injection token when doing http requests:

1const context = new HttpContext().set(BYPASS_ERROR_HANDLING_FOR_STATUS_CODES, [404, 500])
2
3// Pass the HttpContext when doing any kind of request with the HttpClient
4this.http.post<YourModel>(url, payload, { context })

In the example given above, the default error handling will be disabled for the error codes 404 and 500 , but will still be applied to all other error codes.