Angular中全局错误处理的合理方法

时间:2014-03-03 18:50:45

标签: angularjs exception-handling error-handling

这就是我想要的:拥有一个模块,服务或其他东西,它提供了一个全局错误处理程序:

  1. Angular表达式中的错误(所以$exceptionHandler服务捕获的所有内容)
  2. 来自HTTP请求的错误(因此requestErrorresponseError中截获的所有内容均为defined by an $httpProvider
  3. 触发window.onerror的错误(我认为其中包含“Angular”以外的错误,例如来自独立的第三方图书馆)
  4. 理想情况下,我想捕获所有这些错误,并将它们提供给我的Angular应用程序以包含在HTML中,也许可以将它们添加到$rootScope。但是,我做到这一点的微薄尝试已经证明有些令人费解,并不完全成功。

    这是我已经开始工作的另一种不太理想但看似功能的方法:在Angular之外,设置一个全局处理程序w / window.onerror;然后当遇到上面第1项和第2项中的错误时,实际上throw错误(导致所有错误一直到window.onerror)。

    我当然不为这个解决方案感到骄傲,不仅因为它是hacky而且因为它阻止我使用Angular显示错误(相反我必须自己填充DOM)并且因为它剥离了有用的错误信息(因为被捕获的值w / onerror只是一个普通字符串,而不是具有信息属性的对象。)

2 个答案:

答案 0 :(得分:1)

我如何处理错误的一个粗略示例

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
            });
        }
    }

});

答案 1 :(得分:1)

在我的应用程序中,我使用第二种方法来使用拦截器进行错误处理。

我编写了一个服务来覆盖拦截器responseError,我调用了$ rootScope上定义的“openErrorModel”方法,以便在出现错误时打开带有错误消息的错误模型。

这将更清洁和模块化。并且你可以通过这种方式避免重复。

示例代码:

(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));

//注册拦截器

(function (global) {
    "use strict";

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

    }]);

}(this));

PS:我的openErrorModel定义

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

您可以参考Error Handling in angular了解更多信息。