How to track Angular exceptions automatically

Posted May 11, 2016

Guest post by Freyja Spaven, from our service sponsor Raygun

As developers, time is usually of the essence, and even more so during competition hours. Focusing on building your application is what really matters, and hunting down exceptions manually can be a waste of precious time.

You certainly won’t want to spend all that time and effort coding a great app, only for your final end users (or the judges) encountering bugs, or for it to crash entirely.

We need to make sure that when it comes to deployment, our code is flawless.

Angular is extremely useful in its ability to identify exceptions, as it usually indicates why code could have errors. However, it’s often the case that our applications work perfectly on our own dev machines, only to produce a different story on our user’s browsers in production.

This is where an error monitoring and crash reporting software like Raygun can help.

Raygun makes finding and fixing exceptions easy by receiving every exception your Angular web app throws, so you don’t have to trawl through lines of code or build your ownsolution.

It can save precious time and resources during the entire production process, and we hope you will find it useful through the phases of the competition.

We have a free 30 day trial of crash reporting here.

It’s really quick to set up, too – follow the steps below to hook Raygun into your app.

Installation

First, download the tiny Raygun4JS provider script and add it to your project. There's three delivery channels:

Via Bower

bower install raygun4js

From NuGet - in Visual Studio, open up the Package Manager Console and type

Install-Package raygun4js

Manual download - grab the dev version here, or the minified production version here.

Configuration

Next, reference the script - if you're using static HTML add something like <script src="js/raygun.js" type="text/javascript"></script> or add it to your module loader/minifier.

Finally, call the following code before your main Angular logic to set up Raygun4JS:

Raygun.init('YOUR_API_KEY').attach();

You get an API key for each app you create in Raygun, which is available in your Raygun dashboard - there's a free 30-day trial available for you to test it out.

Catching exceptions in Angular

There are at least two options for injecting an unhandled exception function into Angular modules, with a decorator or a factory. Both of these provide your specified implementation of $exceptionHandler, which we will use to send to Raygun via the Raygun4JS provider we referenced above.

Using a decorator

The Decorator pattern is great for injecting behaviour onto arbitrary services ensuring separation of concerns among other desirable properties, and is the preferred way for logging and exception handling as it doesn't override the original behaviour. In Angular this is available on the $provide service, which we will use to implement our own $exceptionHandler function:

app.config(function ($provide) {
    $provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
      return function (exception, cause) {
       Raygun.send(exception);
       $delegate(exception, cause); 
      }
    }])
  });

The $delegate is the instance of the exception handler, which we call to get the original behavior of outputting to the console.

You can also make as many other services available as required:

$provide.decorator("$exceptionHandler", ['$delegate', '$log', function($delegate, $log) { r
 eturn function (exception, cause) { 
  $log.debug('Sending to Raygun'); 
  Raygun.send(exception); 
  $delegate(exception, cause); 
  } 
}])

Depending on what sort of error gets thrown within Angular logic, the cause parameter can be populated. If one occurs within a factory or service you may get the scope available on that parameter, which you can transmit to Raygun as custom data, along with anything else you need, by replacing the Raygun.send call above:

Raygun.send(exception, { cause: cause });

Using a factory

A quick way for getting Raygun into your app's exception handler is to override it using a factory, although this removes the original console logging and you'll need to store the original value then call it again, if you want this functionality.

app.factory('$exceptionHandler', function () { 
 return function (exception) { 
  Raygun.send(exception); 
  }
});

Manually sending errors

Raygun4JS also gives you the ability to manually track errors easily at any time, like this:

Raygun.send(new Error('my custom error'));

There's also a bunch of other useful tools available on the provider, including unique user tracking, version tracking, tags and more - check out the documentation here for all the details.

Raygun even tracks jQuery Ajax errors in your Angular app without any extra effort needed from you, so you get full coverage out-of-the-box.

Sign up for a free trial here (there’s even some free developer swag)

NOTE: We are currently working on support for the new Angular 2 framework