Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Custom Error Handling for Angular

DZone's Guide to

Custom Error Handling for Angular

Do you work with Angular to make web applications? Read on to learn how to use any versions of this framework to handle errors in your code.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

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 in 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 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 $exceptionHandlerto take more action and gather more context when errors occur.

Basic Configuration for Handling 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, we 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 { ] } 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 exceptions 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 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 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 2

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 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 the 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.

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 throwing an 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 dashboard for Angular exception handling

Dashboard for Angular errors, as seen in Rollbar

Manually Handling 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 errors are seen 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 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.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
web dev ,error handling ,angular

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}