Catching global errors in Angular 2 with ErrorHandler


Angular 2 already has a very good error handler. When an error randomly occurs in your code, the Angular’s error handler will catch it and will print the error details in the console. The error details will also include the line number with a link to the source file. In most cases this should be more then enough to help you understand what is happening in your application.

Why would I need a custom error handler?

You can use a custom error handler to format the error messages that are logged into the browser’s console, to catch custom business errors in your application (Authentication/Authorization errors, HTTP 404, etc.) or maybe you want to also send the errors to you backend server for analytics or other reasons. All of the above are valid use cases of using a custom error handler.

Creating a custom error handler

Writing your own error handler is straightforward. You will need to extend Angular’s ErrorHandler class and override the handleError method. This method receives a wrapper of the original error as a parameter. You can find the original error in the error.originalError property. The default implementation uses console.error() to print the error details in the browser’s console.

CustomErrorHandler.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
import {ErrorHandler} from '@angular/core';
export class CustomErrorHandler extends ErrorHandler {
    constructor(){
        super(false);
    }
    public handleError(error: any): void {
        // You can add your own logic here.
        // It is not required to delegate to the original implementation
        super.handleError(error);
    }
}

Extending Angular’s Error Handler

If you want to use your own custom handler you will need to somehow replace the one that Angular is using. Fortunately enough, Angular’s awesome DI engine will allows you to provide custom implementations for different classes.

AppModule.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import {BrowserModule} from '@angular/platform-browser';
import {ErrorHandler} from '@angular/core';
import {AppComponent} from './app.component';
import {CustomErrorHandler} from './CustomErrorHandler';
@NgModule({
    declarations: [ AppComponent ],
    imports: [ BrowserModule ],
    bootstrap: [ AppComponent ],
    providers: [
        {provide: ErrorHandler, useClass: CustomErrorHandler}
    ]
})
export class AppModule {}

In the code above take a look at the providers field in the @NGModule decorator. With the above configuration in place, every time Angular’s DI engine will request an instance of ErrorHandler will receive an instance of our custom implementation CustomErrorHandler.

Creating custom error classes

Sometimes it’s useful to create custom error classes that you can throw in different parts of your application. For example, when the user is doesn’t have access to a specific part of the application you can throw a custom AuthorizationError.

Creating the custom error class

AuthorizationError.ts:

1
2
3
4
5
export class AuthorizationError {
    toString() {
        return 'You are not authorized to view this content!!!';
    }
}

Updating the CustomErrorHandler class

CustomErrorHandler.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {ErrorHandler} from '@angular/core';
import {AuthorizationError} from './AuthorizationError';
export class CustomErrorHandler extends ErrorHandler {
    constructor(){
        super(false);
    }
    public handleError(error: any): void {
        if(error.originalError instanceof AuthorizationError){
            console.info(`[CUSTOM ERROR]:::${error.originalError.toString()}`);
        } else {
            super.handleError(error);
        }
    }
}

Using the new error in your code

app.component.html:

1
<button (click)="throwCustomError()">Throw Authorization Error</button>

app.component.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
import {Component} from '@angular/core';
import {AuthorizationError} from './AuthorizationError';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  throwCustomError() {
    throw new AuthorizationError();
  }
}

Now when you press the Throw Authorization Error button you will see our custom error logging in the browser’s console:

[CUSTOM ERROR]:::You are not authorized to view this content!!!

If you look closely at the CustomErrorHandler class, everything that is not of type AuthorizationError will be delegated to the original Angular’s ErrorHandler.

From this post

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s