Blog |

Custom error handling for Angular

Custom error handling for Angular
Table of Contents

Angular 2+ and AngularJS (version 1) are popular open-source JavaScript MVC frameworks that let you build highly structured, testable and maintainable front-end applications. Angular is most commonly used on single-page applications. Stable and reliable single-page applications depend on solid client-side error monitoring tools and techniques. But getting the right exception data and context isn’t always easy. We’re going to dive into how to capture, handle and debug Angular errors.

Error handling in vanilla JavaScript consists of using try, catch and finally statements. You can also use these statements in Angular modules. However, Angular has a special logic to handle uncaught exceptions. We’ll show you how to create custom error handlers for Angular that you can override to add your own functionality.

Error logging in Angular

The ErrorHandler class in Angular 2+ provides a hook for centralized exception handling. The default implementation of ErrorHandler prints error messages to the console. This service is very simple by design. To intercept the error handling we need to write a custom handler.

On the other hand, uncaught exceptions in AngularJS are all funneled through the $exceptionHandler service. When unmodified, $exceptionHandler sends all uncaught exceptions to the $log.error service. The $log.error service passes the error through to the client’s console.

Here’s how you can create your own error handler:

class ErrorHandler {
  constructor() {}
  handleError(error: any): void;
}
$exceptionHandler(exception, [cause]);

In Angular 2+ the handleError(error: any): void method allows you to implement your own code to do something with the exception, such as recover your app gracefully or report it to an error monitoring service.

In AngularJS 1.X, when we call $exceptionHandler, we can pass two arguments:

  • exception: the exception associated with the error the application encountered.
  • cause: additional context about the cause of the exception.

The second argument, cause, is entirely optional. It can be helpful when you’re writing exception handlers or adding external handling functionality. $exceptionHandler will simply run on its own, and logging uncaught exceptions to the console in production isn’t very useful. Fortunately, Angular has a handful of ways to extend $exceptionHandler to take more action and gather more context when errors occur.

Basic configuration for handling and logging the error in Angular

Let’s understand how error handlers work in both frameworks. In Angular 2+, error handling can be done by creating a CustomErrorHandler which implements ErrorHandler. In AngularJS 1.X we can extend $exceptionHandler to take more action and gather context when errors occur.

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

@Injectable()
export class CustomErrorHandler implements ErrorHandler {
  constructor() {}
  handleError(error) {
    // your custom error handling logic
    console.log(error);
  }
}
angular
  .module('exceptionOverride', [])
  .factory('$exceptionHandler', function() {});

Now in our AppModule we have to add our CustomErrorHandler as a provider. In AngularJS can extend the module by using .factory(). This is an alternative to $provider.factory() inside a chained .config() on the module.

import {NgModule, ApplicationRef, ErrorHandler} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {CustomErrorHandler} from './custom-error-handler';
import {AppComponent} from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  bootstrap: [AppComponent],
  providers: [
    {
      provide: ErrorHandler,
      useClass: CustomErrorHandler,
    },
  ],
})
export class AppModule {}
angular
  .module('exceptionOverride', [])
  .factory('$exceptionHandler', function() {
    return function(exception, cause) {
      exception.message += 'Angular Exception: "' + cause + '"';
      throw exception;
    };
  });

Now any exception in our application will be caught in our custom error handler.

Production error monitoring with Rollbar

In real-world production applications, it’s important to monitor errors so you understand your user’s experience. It’s best to monitor errors so you’re the first to know and can fix the issue before more customers are affected.

Rollbar logs, tracks and analyzes what’s broken and why by using rich contextual data, including detailed stack traces, request params, telemetry on user behavior, affected users and more. This helps developers to quickly identify and fix errors. Learn more about Rollbar’s JavaScript features.

By including the official Rollbar{:target="_blank"} notifier SDK for Angular 2+ or the popular community notifier ng-rollbar for AngularJS 1.X in your Angular application, errors are automatically captured, grouped and reported—and with much more contextual data than the console provides.

The first thing you’ll want to do is sign up for a Rollbar account. Once you’re signed up, you’ll create a new project and select your Rollbar SDK.

Angular{: .imgcaption} Creating an Angular 2+ Project, as seen in Rollbar

Next, you\'ll see installation instructions and a client-side access token which you’ll need to use to send events and log Angular errors to Rollbar.

Installing Rollbar

To install Rollbar in Angular 2+, simply run the command given in the Angular 2+ tab example below. In Angular JS 1.X, you need to follow some simple steps, shown in the AngularJS 1.X tab example.

npm install rollbar --save
bower install ng-rollbar --save

// Then, include the SDK in your application with this script tag:

<script type="text/javascript" src="bower_components/ng-rollbar/ng-rollbar.min.js"></script>

Configuring Rollbar with your Angular app

In Angular 2+, you’ll need to update your application’s CustomErrorHandler; we will rename it to RollbarErrorHandler. Remember to add your own access token which you received earlier! You’ll also notice that we added a function called rollbarFactory in the example. This creates a named factory that is necessary when using ahead-of-time (AOT) compilation. If you want to follow along yourself, you can find our working example project on GitHub.

In AngularJS 1.X, you’ll need to inject the library into your app and then add the RollbarProvider to your config. Remember to add your own access token, which you received earlier, as well as your environment name to begin logging errors in Angular.

import * as Rollbar from 'rollbar';
import {BrowserModule} from '@angular/platform-browser';
import {
  Injectable,
  Injector,
  InjectionToken,
  NgModule,
  ErrorHandler,
} from '@angular/core';
import {AppComponent} from './app.component';

const rollbarConfig = {
  accessToken: 'YOUR_ACCESS_TOKEN',
  captureUncaught: true,
  captureUnhandledRejections: true,
};

@Injectable()
export class RollbarErrorHandler implements ErrorHandler {
  constructor(private injector: Injector) {}

  handleError(err: any): void {
    var rollbar = this.injector.get(RollbarService);
    rollbar.error(err.originalError || err);
  }
}

export function rollbarFactory() {
  return new Rollbar(rollbarConfig);
}

export const RollbarService = new InjectionToken<Rollbar>('rollbar');

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    {provide: ErrorHandler, useClass: RollbarErrorHandler},
    {provide: RollbarService, useFactory: rollbarFactory},
  ],
})
export class AppModule {}
var app = angular.module('myApp', ['tandibar/ng-rollbar']);

app.config(function(RollbarProvider) {
  RollbarProvider.init({
    accessToken: 'YOUR_ACCESS_TOKEN',
    captureUncaught: true,
    payload: {
      environment: 'YOUR_ENVIRONMENT',
    },
  });
});

Testing the sample application

You can test if everything was set up correctly by opening a console window and entering:

window.onerror(
  'TestRollbarError: testing window.onerror',
  window.location.href
);

or logging and throwing an Angular error in an application like this:

throw new Error('Hello World, Error Message');

Once everything is installed correctly, you should see the TestRollbarError in the Rollbar dashboard as shown below.

Rollbar{: .imgcaption} Dashboard for Angular errors, as seen in Rollbar

Manually logging custom Angular errors with Rollbar

You may decide to manually handle errors. This gives you extra control over the information passed to Rollbar. Just inject Rollbar into the corresponding Angular component. The code looks something like this:

@Component()
export class MyComponent {
  constructor(private rollbar: Rollbar) {}
  manualHandle() {
    this.rollbar.error(this.errorMessage);
  }
}
myApp.controller('MainCtrl', function($scope, Rollbar) {
  $scope.onSomeEvent = function() {
    Rollbar.error('this is an error with special handling');
  };
});

You may flag errors by severity in both frameworks so that the most critical Angular errors are seen, logged and handled first. You can also pass extra data to help with debugging.

// Rollbar severities
rollbar.critical('some critical error'); // most severe
rollbar.error('some error');
rollbar.warning('some warning');
rollbar.info('some info');
rollbar.debug('some debug message'); // least severe

Debugging Angular errors with Rollbar

Now that you have Rollbar integrated into your Angular app, any errors that occur automatically get captured, grouped, logged and reported to your new project in Rollbar. You’ll be able to quickly and easily see which errors are occurring and how often they occur, as well as the full context and analytics into all of your exceptions. You can set alert notifications on any of the errors and have them delivered to your email. Rollbar collects a wide variety of context data for each error, including detailed stack traces, request params, URL, environment, affected users, browser, location, host and much more. I hope this was a helpful introduction to error handling in Angular that shows how easy it is to get started.


If you haven’t already, signup for a 14-day free trial of Rollbar and let us help you take control of pesky Angular errors. 🙂

"Rollbar allows us to go from alerting to impact analysis and resolution in a matter of minutes. Without it we would be flying blind."

Error Monitoring

Start continuously improving your code today.

Get Started Shape