装饰$ errorProvider时的循环引用

时间:2015-03-26 21:26:33

标签: javascript angularjs error-handling circular-dependency

在我正在进行的项目中,我正在按照项目主管的要求开发实施开发人员通知系统。它的工作方式是,如果发生前端错误,开发团队会收到错误的电子邮件。

然而,在我当前的实现中,似乎我有以下循环依赖:

$rootScope <- $http <- $exceptionHandler <- $rootScope

在以下代码中:

(function() {
    'use strict';

    // Using .config to 'decorate' the exception handler.
    angular.module('app').config(function($provide) {
        $provide.decorator('$exceptionHandler', ['$delegate', '$http', dispatchErrorEmail]);
    });

    function dispatchErrorEmail($delegate, $http) {
        return function (exception, cause) {
            // Execute default implementation.
            $delegate(exception, cause);

            // Angular exceptions fail softly, but generate an error email.
            var args = {
                'exception': exception,
                'cause': cause
            };
            $http.post('/api/admin/ErrorNotification', args);
        };
    }
})();

正如您所看到的,有一个问题:$rootScope的装饰中,我实际上并没有以任何方式使用$errorHandler

更重要的是,$provide.decorator$errorHandler文档都没有隐含地包含$rootScope的任何注释。

问题:

  1. 究竟如何将$rootScope注入此服务?
  2. 我可以用什么方式重写$exceptionHandler装饰以避免这种循环依赖?

2 个答案:

答案 0 :(得分:2)

稍微考虑一下 - 特别是在相关侧边栏上 - 引导我this answer。差不多,我必须使用$injector来获取$http服务的实例句柄。

(function() {
   'use strict';

    // Using .config to 'decorate' the exception handler.
    angular.module('app').config(function($provide) {
        $provide.decorator('$exceptionHandler', ['$delegate', '$injector', dispatchErrorEmail]);
    });

    function dispatchErrorEmail($delegate, $injector) {
        return function (exception, cause) {
            // Execute default implementation.
            $delegate(exception, cause);

            // Angular exceptions fail softly, but generate an error email.
            var $http = $injector.get('$http');
            var args = {
                'exception': exception,
                'cause': cause
            };
            $http.post('/api/admin/ErrorNotification', args);
        };
    }
})();

这并不能解释为什么 $rootScope潜入$exceptionHandler服务;我想我必须坚信这一点。

答案 1 :(得分:1)

我有类似的问题,你的帖子帮助我找到了解决方案。我有一个公共库,我用于几乎所有常见的页面活动,如显示吐司和管理加载指示器。您的解决方案有助于使用注入器访问该服务。希望这有助于其他人!

// custom exception handling
module.config(function ($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', '$injector', function ($delegate, $injector) {
        return function (exception, cause) {
            $delegate(exception, cause);
            var common = $injector.get('common');
            common.toast('Whoops, an error occurred!');
            common.loading(false);
        };
    }]);
});