Global Error Handling with Angular2+

Austin
Austin
Mar 22, 2017 · 3 min read
Image for post
Image for post

Error handling is one of those things no one wants to deal with, well in Angular you can create a global handler and never have to worry again.

Angular defines an ErrorHandler class that will allow us to override it and handle custom logic. Typically, I have my error handlers do things like:

  • Show some sort of notification to the user via a dialog or growl-like component (ideally with a emoji)
  • Send the error details to the server for logging

Whatever you're doing in this logic, here’s how we go about it…

First, let's define a GlobalErrorHandler class that will inherit from ErrorHandler like so:

import { ErrorHandler, Injectable} from '@angular/core';

Now in our module, we have to tell Angular to use our GlobalErrorHandler instead of the default one like:

import { NgModule, ApplicationRef, ErrorHandler } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { GlobalErrorHandler } from './error-handler';
import { ServicesModule } from './services';

import { AppComponent } from './app.component';

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
bootstrap: [AppComponent],
providers: [
{
provide: ErrorHandler,
useClass: GlobalErrorHandler
}
]
})
export class AppModule { }

Now we if we just do throw new Error('Im errorn') anywhere in our application, we will see our cool console message.

There is one problem though, since error handling is really important it needs to be loaded first, thus making it not possible to use dependency injection in the constructor to get other services such as the error handle api service to send the server our error details. As a result, we have to manually call the injector with the service name in the execution of the handleError function like:

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { LoggingService } from '../services';
import * as StackTrace from 'stacktrace-js';

That one stumped me for a bit, but to wrap things up I like to use StackTrace.js to get the full stack and also add the current URL to the message going upstream to the server, so the final implementation looks something like:

import { ErrorHandler, Injectable, Injector } from '@angular/core';
import { LocationStrategy, PathLocationStrategy } from '@angular/common';
import { LoggingService } from '../services';
import * as StackTrace from 'stacktrace-js';

Image for post
Image for post
I’m #ngPanda

I hope you enjoyed the post, if you liked it follow me on Twitter and Github for more JavaScript tips/opinions/projects/articles/etc!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store