Question

Here's what I'd like: to have a module, or service, or something, that provides a global error handler for:

  1. Errors in Angular expressions (so everything caught by the $exceptionHandler service)
  2. Errors from HTTP requests (so everything intercepted in requestError and responseError as defined by an $httpProvider)
  3. Errors triggering window.onerror (which I believe will include errors occurring "outside" Angular, e.g., from independent 3rd party libraries)

Ideally, I'd like to capture all such errors and make them available to my Angular app for inclusion in the HTML, perhaps by adding them to the $rootScope. But my meager attempts to accomplish this far have proven somewhat convoluted and not entirely successful.

Here's an alternate, less-than-ideal but seemingly-functional approach I have gotten to work: outside Angular, set a global handler w/ window.onerror; then when encountering errors in items 1 and 2 above, actually throw the errors (causing everything to make it all the way to window.onerror).

I'm certainly not proud of this solution, not only because it's hacky but also because it prevents me from displaying the errors using Angular (instead I have to populate the DOM myself) and because it strips away useful error information (since the value trapped w/ onerror is just a plain string as opposed to an object with informative properties).

No correct solution

OTHER TIPS

A rough example of how I've been handling errors

var pageModule = angular.module('pageModule',[])
.service('myService',function($http) {
    return {
        someHttpCall : function() {
            return $http.get('myHttpCall');
        }
    }
})
.controller('parentCtrl',function($scope,myService) {
    myService.someHttpCall()
    .success(function(response) {
        //
    })
    .error(function(response) {
        $scope.$emit('errorEvent', {
            type    : 'networkError',
            message : 'There was a network error with this ajax call'
        });

    });

    $scope.someFunction = function() {
        if(error) {
            $scope.$emit('errorEvent', {
                type    : 'myErrorType',
                message : 'My message about error here'
            });
        }
    }
})
.controller('childCtrl',function($scope) {
    $scope.someFunctionInChildScope = function() {
        if(error) {
            $scope.$emit('errorEvent', {
                type    : 'myOtherErrorType',
                message : 'My other message about error here'
            });
        }
    }
})
.directive('myErrorMessage',function($rootScope) {
    return {
        link : function($scope,$element,$attrs) {
            $rootScope.$on('errorEvent',function(event,errorObj) {
                //compile and append an error here.. based on errorObj
            });
        }
    }

});

In my application i used 2nd approach to use interceptors for error handling.

I wrote a service to override interceptor responseError,and i called "openErrorModel" method defined on $rootScope to open error model with error message when ever there is error.

This would be cleaner and modularized. and you can avoid duplication this way.

Sample code:

(function (global) {
    "use strict";

    angular.module("TestAPp").factory('httpInterceptor', ["$rootScope", "$q", function ($rootScope, $q) {
        return {
        responseError: function (response) {
            /* Open Error model and display error */
            $rootScope.openErrorModel(response);
            /* reject deffered object so that it'll reach error block , else it'll execute success function */
            return $q.reject(response);
        }
        };
    }]);

}(this));

//registering interceprtor

(function (global) {
    "use strict";

    angular.module("TestApp", [])
           .config([ '$httpProvider',function ($httpProvider) {
                /* Register the interceptor */
                $httpProvider.interceptors.push('httpInterceptor');

    }]);

}(this));

PS: My openErrorModel definition

$rootScope.openErrorModel = function (error) {
      $rootScope.errorMessage = error.data;
      $('#errorModal').modal('show');
};

You can refer to Error Handling in angular for more info.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top