Angular:在正常情况下,我可以确保在$ exceptionHandler之前配置我的日志记录模块吗?

时间:2015-07-06 16:39:56

标签: javascript angularjs dependency-injection raygun

我正在编写错误记录模块,以将Raygun日志记录添加到AngularJS应用程序中。 standard method是注册$exceptionHandler的装饰器,如下所示:

$provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
    return function (exception, cause) {
      Raygun.send(exception);
      $delegate(exception, cause);
    }
  }])

但是,这具有顺序依赖性,因为必须在DI框架首次加载$exceptionHandler之前安装装饰器。如果我将此代码包装在一个模块中,那么顺序依赖性就更不明显了,客户端很容易以错误的顺序初始化事物并且不知道为什么Raygun.send不是&# 39;被叫。 (我是那个客户一天半。在我的辩护中,这是我第一次使用Angular。)

我想说服Angular的DI框架在$exceptionHandler之前加载我的错误记录模块,明显需要注意的是,如果有任何异常被抛出的话在引导中。我曾尝试将我的模块注册为$exceptionHandler的依赖关系,但是还没有能够弄清楚如何做到这一点 - 而且,{{1取决于我的代码。是否有一种惯用的方法可以解决这个问题?

1 个答案:

答案 0 :(得分:0)

Angular在其自己的$exceptionHandler模块实例化期间,在其自己的配置阶段实例化ng-和所有其他ng服务。只需将代码移动到ng模块的配置:

angular.module('ng')
.config(['$provide', function($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', function($delegate) {
        return function (exception, cause) {
            Raygun.send(exception);
            $delegate(exception, cause);
        }
    }]);
}]);

$exceptionHandler实例化后,此配置将立即放入队列中。

但是,配置/运行错误委托给$exceptionHandler或任何角度记录器,它们只是未被捕获,传播到堆栈的末尾。您可以捕获这些例外,但必须manually bootstrap angular。删除ng-app属性,然后运行以下代码:

angular.element(document).ready(function() {
    try {
        angular.bootstrap(document, ['yourModule']);
    } catch (exception) {
        Raygun.send(exception);
        throw exception;
    }
});

如果两个错误都通过$exceptionHandler并且在引导过程中被捕获,则不应该报告错误。

示例plunker: http://plnkr.co/edit/XsiMNA7GIbHzXyjEioxy?p=preview
打开你的控制台并取消注释第9行或第15行中script.js中的一个错误。你应该看到角度的常规错误处理以及一个虚拟的Raygun.send日志警告到控制台。