HttpInterceptor in Angular 4.3: Intercepting 400 error responses

Viewed 20823

I would like to intercept 401 and other errors in order to react accordingly. This is my interceptor:

import { LoggingService } from './../logging/logging.service';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Injectable()
export class TwsHttpInterceptor implements HttpInterceptor {

    constructor(private logger: LoggingService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this.logger.logDebug(request);    
        return next.handle(request)
            .do(event => {
                if (event instanceof HttpResponse) {
                    this.logger.logDebug(event);
                }
            });
    }
}

While this works well for 200 requests, it does not intercept the error respsonses

All I see in chrome's dev console is this:

zone.js:2616 GET http://localhost:8080/backend/rest/wrongurl 404 (Not Found)

Or this

zone.js:2616 GET http://localhost:8080/backend/rest/url 401 (Unauthorized)

I would like my interceptor to deal with this. What am I missing ?

4 Answers

At the time I was trying Angular 7+.

Unfortunately above solutions did not serve the job well because .do is not directly available on HttpHandler as of RxJs 6 pipes notion; and converting Observable to Promise does not stick.

Here is clean and up-to-date approach; I pipe the catchError operator and analyze the error and finally re-throw it by using throwError. Here is final shape of interceptor;

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(req).pipe(
      catchError((error: HttpErrorResponse) => {
        if (error.error instanceof ErrorEvent) {
          // client-side error or network error

        } else {
          // TODO: Clean up following by introducing method
          if (error.status === 498) { 
            // TODO: Destroy local session; redirect to /login
          }
          if (error.status === 401) { 
            // TODO: Permission denied; show toast
          }
        }
        return throwError(error);
      })
    );
  }

Hopefully this solution will help someone in future.

To intercept Http response error in angular 6, I make a little trick converting Observable to Promise:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   const obs = next.handle(req);

   if (!window.navigator.onLine) {
     // Handle offline error
     this.messageService.showError('No Internet Connection');
     return;
   }

   obs.toPromise().catch((error) => {
     this.messageService.progress(false);
     this.messageService.showError(error.message);
   });
   return obs;
}
Related