Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpInterceptor in Angular 4.3: Intercepting 400 error responses

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 ?

like image 625
Tim Avatar asked Jul 28 '17 07:07

Tim


People also ask

What is HttpInterceptor in angular?

HTTP Interceptors is a special type of angular service that we can implement. It's used to apply custom logic to the central point between the client-side and server-side outgoing/incoming HTTP request and response. Keep in mind that the interceptor wants only HTTP requests.

What is the use of HttpInterceptor?

An HTTP interceptor can be useful if there is some logic, such as an auditing requirement, that you want executed for every request and response. By placing the logic in the interceptor, you ensure that Integration Server executes the logic for every HTTP request and response.

Can Angular have multiple HTTP interceptors?

So how can I add multiple interceptors? Http doesn't allow to have more than one custom implementation. But as @estus mentioned the Angular team has added a new HttpClient service recently (release 4.3) which supports multiple interceptors concept. You don't need to extend the HttpClient as you do with the old Http .

What is the use of interceptors in angular 4?

Interceptors are a unique type of Angular Service that we can implement. Interceptors allow us to intercept incoming or outgoing HTTP requests using the HttpClient . By intercepting the HTTP request, we can modify or change the value of the request.


2 Answers

Http sends errors down the error stream of an observable so you will need to catch them with .catch (you can read more about this here).

return next.handle(request)
  .do(event => {
    if (event instanceof HttpResponse) {
      this.logger.logDebug(event);
    }
  })
  .catch(err => { 
    console.log('Caught error', err);
    return Observable.throw(err);
  });
like image 189
0mpurdy Avatar answered Oct 11 '22 06:10

0mpurdy


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.

like image 25
mumair Avatar answered Oct 11 '22 06:10

mumair