How to override $exceptionHandler implementation

JavascriptException HandlingAngularjs

Javascript Problem Overview


There are some extra things we want to do anytime a javascript exception is thrown.

From the docs on $exceptionHandler:

> Any uncaught exception in angular expressions is delegated to this service. The default implementation simply delegates to $log.error which logs it into the browser console.

The fact that it says "default implementation" makes me think there's a way we can provide our own implementation for the service, and do the stuff we want when an exception is thrown. My question is, how do you do this? How can we keep all exceptions going to this service, but then provide functionality we want to happen?

Javascript Solutions


Solution 1 - Javascript

Another option I've found for this is to "decorate" the $exceptionHandler through the $provide.decorator function. This provides you with a reference to the original implementation if you want to use it as part of your custom implementation. So, you can do something like this:

mod.config(function($provide) {
    $provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
		return function(exception, cause) {
			$delegate(exception, cause);
            alert(exception.message);
		};
	}]);
});

It will do what the original exception handler does, plus custom functionality.

See this updated fiddle.

Solution 2 - Javascript

You can override the $exceptionHandler functionality by creating a service with the same name:

var mod = angular.module('testApp', []);

mod.factory('$exceptionHandler', function () {
    return function (exception, cause) {
        alert(exception.message);
    };
});

See this fiddle for a sample. If you comment out the factory definition for $exceptionHandler you will see the error will log to the console instead of alerting it.

Here is a group thread that has an example of injecting other services like $http using $injector.

Note: if you don't want to overwrite the existing functionality of the $exceptionHandler (or another built in service) see this answer for information on how to decorate a service.

Solution 3 - Javascript

You can override any service/factory even $cookieStore.If you want a full-blown, configurable object here is a really nice example:

var myApp = angular.module('myApp', []);

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});
        

function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
    
   helloWorld.sayHello(),
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondnc253View Question on Stackoverflow
Solution 1 - Javascriptdnc253View Answer on Stackoverflow
Solution 2 - JavascriptGloopyView Answer on Stackoverflow
Solution 3 - JavascriptBartek SkwiraView Answer on Stackoverflow