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 ?
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.
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.
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 .
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.
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);
});
At the time I was trying Angular 7+.
Unfortunately above solutions did not serve the job well because
.do
is not directly available onHttpHandler
as of RxJs 6 pipes notion; and convertingObservable 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With