Angular Error Interceptor

Satyapriya Mishra
4 min readFeb 11, 2020

--

Before going into error interceptor, first let’s understand what is an interceptor.

Interceptor

An interceptor is a piece of code that intercepts an operation when it just gets triggered and just before it nears its completion. In the Angular environment an interceptor is used mostly while making an HTTP call to any source outside of the client. A typical use case is the addition of headers or tokens for identifying the source/origin of the HTTP request.

Error Interceptor

An error interceptor is a special type of interceptor which is used for handling errors that arise while making an HTTP request. The error may come in either the client side (browser) or it may be an error from the server side when the request fails due to any reason. Error handling is very important for any modern day application as it is very imperative to do the next course of actions if some request response cycle fails. This is where the mechanism of error interceptor comes into play.

TL;DR for the sake of simplicity, in this article we will take into consideration a very simple use case where the API end point is wrong and we will capture the error arising thereof. All sorts of error arising out of API calls can be captured in the same fashion.

For the sake of code, we will have a component which makes use of a very simple service method to make an HTTP call. Eventually the HTTP request will fail due to incorrect end point and we will capture the error.

Let’s first define the button which we will use to make the API call.

app.component.html

<div>
<button (click) = ‘someApiCall()’>Click Me!</button>
</div>

Simple enough right ! Nothing fancy happening here. Let’s move to the next part where we will be writing some code in response to the button click.Before anything else let’s write the service (called DataService) with a method getData() which makes this HTTP call.

data.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }getData(): Observable<any> {
const url = 'Some wrong url for test purpose';
return this.http.get(url);
}
}

Nothing fancy happening here, right. Just a method called getData() which when invoked from the component will make an API call to some wrong end point. The end point is knowingly kept wrong so as to get error and eventually we will see how we will do the error handling from the error interceptor.

Now let’s explore the main part of this article i.e the error interceptor. Let’s create a new file inside the services folder and name it as httperrorinterceptor.service.ts. This is the file where we will be writing the error interceptor logic. In the file we will have a very basic structure for error handling and we will see how to take care of different kinds of errors. Let’s have the following content in the httperrorinterceptor.service.ts file.

import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
catchError((error: HttpErrorResponse) => {
let errorMsg = '';
if (error.error instanceof ErrorEvent) {
console.log('this is client side error');
errorMsg = `Error: ${error.error.message}`;
}
else {
console.log('this is server side error');
errorMsg = `Error Code: ${error.status}, Message: ${error.message}`;
}
console.log(errorMsg);
return throwError(errorMsg);
})
)
}
}

Quite a few things are happening here. Long story short, we will touch the most important points here.

  1. the HttpErrorInterceptor class implements the HttpInterceptor interface which is imported as part of @angular/common/http npm package.This is basically to implement the intercept() method.
  2. the intercept method takes two parameters namely request which is of type HttpRequest and next which is of type HttpHandler.
  3. the intercept method returns an Observable which of type HttpEvent with a signature any. You can have the type set to any custom type.
  4. inside the rxjs pipe() operator we are checking if the error is an instance of ErrorEvent. This check is done to verify if the error is arising out of the client side.
  5. else we take the error as a server side generated error.
  6. for the sake of simplicity of demonstration we are just forming an error message with ES6 interpolation operator and returning the error through the throwError() operator of rxjs. You can also show some sort of alert message with toastr with the return value.

That is all from this file.

Now heading on to the final step, we will register the above file with out app module. So let’s move to the app.module.ts file and make some minor changes.

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './services/httpinterceptor.service';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }

Here we simply import the HttpErrorInterceptor class from the service file and register it in the providers array.One thing to note here is that the interceptor file is provided as HTTP_INTERCEPTORS and we have kept multi as true to facilitate the provision for multiple interceptors.

This is a very basic implementation of Angular error interceptors and complex logic can be built from this gateway.

--

--