0

我正在编写一个错误日志记录模块来将 Raygun 日志记录添加到 AngularJS 应用程序。标准方法是注册一个装饰器,如下$exceptionHandler所示:

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

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

我想说服 Angular 的 DI 框架在之前加载我的错误记录模块$exceptionHandler,但有一个明显的警告是,如果在引导过程中很早就抛出任何异常,我会感到很沮丧。我想尝试将我的模块注册为 的依赖项$exceptionHandler,但还没有弄清楚如何做到这一点——而且,这实际上并不$exceptionHandler取决于我的代码。有没有一种我想念的惯用方法来做到这一点?

4

1 回答 1

0

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

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任何角度记录器,它们只是未被捕获,传播到堆栈的末尾。您可以捕获这些异常,但您必须手动引导 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 打开控制台并取消注释 script.js 中第 9 行或第 15 行的错误之一。您应该看到 angular 的常规错误处理以及虚拟 Raygun . 向控制台发送日志警告。

于 2016-05-30T03:28:55.393 回答