DEV Community

Preston Lamb
Preston Lamb

Posted on • Originally published at prestonlamb.com on

Angular HTTP Error Interceptors

Angular 4.3 introduced HTTP interceptors. This gives you the ability to handle every outgoing http call and every incoming response, all in one spot. Most of the examples I've seen out there cover the first, with each call having an authentication token attached to the call. I needed a way to handle and display errors on HTTP calls, and didn't want to put the error handling on every single call I make. This is a quick example of how to implement this in your app.

As I mentioned, HTTP_INTERCEPTORS was introduced in Angular 4.3. To use them, you need to use the HttpClient that's in the @angular/common/http package, not @angular/http. To write a custom interceptor, you need to implement HttpInterceptor, which requires an intercept method. It's in that method that you can catch errors and handle them. Below is an example:

_ Edit: the first example is for RxJS pre 6.0 release. The second example is for RXJS 6.0+._

// RxJS < 6.0
return next.handle(req)
    .do((ev: HttpEvent) => {
        if (ev instanceof HttpResponse) {
            console.log('ev in the do: ', ev);
        }
    })
    .catch((response: any) => {
        if (response instanceof HttpErrorResponse) {
            console.log('response in the catch: ', response);
            toaster.error('Unexpected Error', response.message);
        }

        return Observable.throw(response);
    });

// RxJS 6.0+
return next.handle(req).pipe(
    tap(
        (incoming: any) => {},
        (error: HttpErrorResponse) => {
            // Handle Error
            return of(error);
        }
    )
)
Enter fullscreen mode Exit fullscreen mode

Handling the error here takes place in the catch method. I'll show a little more about where the toaster variable comes from in a minute, but that's how the errors are globally shown for the app.

For this interceptor to actually work, you need to provide it in the app.module.ts file, under the providers attribute for the module. Do that like this:

...
{
    provide: HTTP_INTERCEPTORS,
    useClass: ErrorInterceptorService,
    multi: true
}
...
Enter fullscreen mode Exit fullscreen mode

This is the basic way to catch all the errors globally for your app. I'll now show a little more specifics of the route I took. I am using angular2-toaster to show the errors when one comes back. I made a service, ToasterNotificationService, that wraps the package's function to show errors. That service needs to be injected into the interceptor service we made. We need to explicitly use the Angular injector to get an instance of the ToasterNotificationService. Do that like this:

intercept (req: HttpRequest, next: HttpHandler): Observable> {
    const toaster = this.injector.get(ToasterNotificationService);

    ...
}
Enter fullscreen mode Exit fullscreen mode

Also, make sure to include the custom ToasterNotificationService, the ToasterModule (from angular2-toaster), and the ToasterService into the app.module.ts's providers and module declarations.

With all of this set up, you should be able to catch the error and then use the toaster notification service to display that error. angular2-toaster has proven to be a simple way to show those errors without having to rewrite a lot of custom code. There is a lot of customization that you can do as well; check out their docs to see that.

Hopefully this all helps you in some way. But to make it a little better, I have put together a little example Angular app to show all this work. It's located right here on GitHub. This StackBlitz project also has an example of this. Check it out, and let me know if you have any questions. You can reach me on Twitter or by email. Thanks for taking the time to read this, and hopefully it helped in some way!

Top comments (0)