简体   繁体   English

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

[英]Angular: Can I ensure that my logging module gets configured before $exceptionHandler under normal circumstances?

I'm writing an error-logging module to add Raygun logging to an AngularJS application. 我正在编写一个错误记录模块,以将Raygun记录添加到AngularJS应用程序。 The standard method is to register a decorator for $exceptionHandler like so: 标准方法是为$exceptionHandler注册一个装饰器,如下所示:

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

However, this has an order dependence in that the decorator must be installed before the DI framework first loads $exceptionHandler . 但是,这具有顺序依赖性,因为必须在DI框架首先加载$exceptionHandler之前安装装饰器。 If I'm wrapping this code in a module, the order dependence is even less obvious, and it's easy for the client to initialize things in the wrong order and have no idea why Raygun.send isn't getting called. 如果我将此代码包装在模块中,则顺序依赖性甚至不那么明显,并且客户端很容易以错误的顺序初始化事物,而且不知道为什么未调用Raygun.send (I was that client for a day and a half. In my defense, this is my first experience with Angular.) (我是那个客户一天半。为我辩护,这是我第一次体验Angular。)

I'd like to persuade Angular's DI framework to load my error-logging module before $exceptionHandler , with the obvious caveat that I'm hosed if any exceptions are thrown really early in bootstrapping. 我想说服Angular的DI框架在$exceptionHandler之前加载我的错误记录模块,明显的警告是,如果在引导过程中真的引发了任何异常,我会被束之高阁。 I thought of trying to register my module as a dependency of $exceptionHandler , but haven't been able to figure out how to do that yet -- also, it's not actually true that $exceptionHandler depends upon my code. 我想到尝试将模块注册为$exceptionHandler的依赖项,但还没有弄清楚该怎么做-而且, $exceptionHandler依赖于我的代码实际上并不是真的。 Is there an idiomatic way to do this that I'm missing? 有我惯用的惯用方法吗?

Angular instantiates $exceptionHandler and all other ng- services during its own config phase, during its own ng module instantiation. Angular在其自己的ng模块实例化期间,在其自己的配置阶段实例化$exceptionHandler和所有其他ng- service。 Simply move your code to a config of the ng module: 只需将您的代码移动到ng模块的配置中即可:

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

This configuration will be placed in the queue immediately after $exceptionHandler gets instantiated. $exceptionHandler实例化后,此配置将立即放入队列中。

However, config/run errors are not delegated to $exceptionHandler or any angular logger, they are simply uncaught, propagating to the end of the stack. 但是,配置/运行错误不会委托给$exceptionHandler或任何角度记录器,它们只是未被捕获,一直传播到堆栈的末尾。 You can capture these exceptions, but you must manually bootstrap angular . 您可以捕获这些异常,但是必须手动引导angular Remove the ng-app attribute, and instead run this code: 删除ng-app属性,然后运行以下代码:

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

With both errors caught passing though the $exceptionHandler and caught during bootstrapping, there shouldn't be an error that doesn't get reported. 由于两个错误都通过$exceptionHandler传递并在引导过程中被捕捉,因此不应有未报告的错误。

Example plunker: http://plnkr.co/edit/XsiMNA7GIbHzXyjEioxy?p=preview 例子: http ://plnkr.co/edit/XsiMNA7GIbHzXyjEioxy?p = preview
Open your console and uncomment one of the errors in script.js on line 9 or 15. You should see angular's regular error handling as well as a dummy Raygun.send logging warnings to the console. 打开控制台,并取消注释第9或15行上script.js中的错误之一。您应该看到angular的常规错误处理以及虚拟的Raygun.send日志警告发送到控制台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM