如何覆盖$ exceptionHandler实现

dnc*_*253 73 javascript exception-handling angularjs

在抛出javascript异常的任何时候我们都想做一些额外的事情.

来自以下文档$exceptionHandler:

角度表达式中的任何未捕获的异常都委托给此服务.默认实现只是委托给$ log.error,它将其记录到浏览器控制台中.

它说"默认实现"的事实使我认为有一种方法可以为服务提供我们自己的实现,并在抛出异常时执行我们想要的操作.我的问题是,你是怎么做到的?我们如何将所有异常保留在此服务中,然后提供我们希望发生的功能?

dnc*_*253 173

我发现的另一个选择是$exceptionHandler通过$ provide.decorator函数"装饰" .如果要将其用作自定义实现的一部分,这将为您提供对原始实现的引用.所以,你可以这样做:

mod.config(function($provide) {
    $provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
        return function(exception, cause) {
            $delegate(exception, cause);
            alert(exception.message);
        };
    }]);
});
Run Code Online (Sandbox Code Playgroud)

它将执行原始异常处理程序的功能,以及自定义功能.

看到这个更新的小提琴.

  • +1就此而言 - 这是解决问题的更好方法. (2认同)

Glo*_*opy 56

您可以$exceptionHandler通过创建具有相同名称的服务来覆盖该功能:

var mod = angular.module('testApp', []);

mod.factory('$exceptionHandler', function () {
    return function (exception, cause) {
        alert(exception.message);
    };
});
Run Code Online (Sandbox Code Playgroud)

一下这个小提琴样本.如果您注释掉工厂定义,$exceptionHandler您将看到错误将记录到控制台而不是警告它.

这是一个组线程,它有一个注入其他服务的例子,比如$http使用$injector.

注意:如果您不想覆盖$exceptionHandler(或其他内置服务)的现有功能,请参阅此答案以获取有关如何装饰服务的信息.

  • 我非常喜欢@ dnc253的解决方案.通过使用"装饰器"功能,您可以保留现有行为并允许其他装饰器参与操作.这个会破坏已经存在的任何东西,包括你自己的代码,如果你已经在其他地方出于另外的原因这样做了. (9认同)
  • 我完全同意装饰者是一种更干净的方式来做到这一点. (2认同)