Piping Global Errors Into The $exceptionHandler Service In AngularJS
Out of the box, AngularJS has excellent error handling in so much as that everything that AngularJS "knowns about" is executed inside of a try/catch block. These managed errors are handed off to the $exceptionHandler service, where your application may or may not process them further. But, errors that happen outside of an AngularJS workflow, such as those that happen in a jQuery plugin, go off into the void. As such, I wanted to see if I could catch those unhandled errors and pipe them into the core $exceptionHandler service.
The global error handler - window.onerror - is, from what I have read, a rather old and outdated feature and is not standardized across browsers. As such, if you are using a "professional" 3rd-party script that handles client-side errors, you are going to be better off just letting that script manage the errors. This exploration attempts to manage errors in the absence of such a script (though I do my best to not overwrite any existing window.onerror functionality).
Because we are trying to handle errors that happen outside of the AngularJS workflow, I think this functionality is best configured in a "run block" that executes after the AngularJS application is bootstrapped. You might be tempted to try to "decorate" the $window service during the configuration phase (my first attempt). However, you will run into a circular dependency-injection reference between $window, $exceptionHandler, and $log.
In the following code, I attach a new $window.onerror function which turns around and sends the error object to the $exceptionHandler service. The assumption with this approach is that the $exceptionHandler service is either being overridden or decorated by something else in the AngularJS application.
When I mouse-over the problematic <P> element, the error is caught by my global error handler and passed off to the $exceptionHandler service, where it is [by default] logged to the console:
As you can see, the original error handler was left in tact even though we added our own error handling logic.
Again, you are probably going to be better off using a professional error handling vendor script. But, as a first step, this kind of approach will at least try to unify the way you are handling errors in your AngularJS application. And, at that point, you can decorate the $exceptionHandler service to track errors that happen both inside and outside of AngularJS workflows.
Want to use code from this post? Check out the license.