Bypass Interceptors with HTTP_CONTEXT_TOKEN
October 11, 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.