如何覆盖 $exceptionHandler 实现

Posted

技术标签:

【中文标题】如何覆盖 $exceptionHandler 实现【英文标题】:How to override $exceptionHandler implementation 【发布时间】:2012-11-15 17:41:40 【问题描述】:

每当抛出 javascript 异常时,我们都想做一些额外的事情。

来自$exceptionHandler 上的文档:

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

它说“默认实现”的事实让我认为有一种方法可以为服务提供我们自己的实现,并在抛出异常时做我们想要的事情。我的问题是,你是怎么做到的?我们如何才能将所有异常都发送到此服务,然后提供我们希望发生的功能?

【问题讨论】:

请选择“$provide.decorator”解决方案作为此问题的答案。 【参考方案1】:

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

mod.config(function($provide) 
    $provide.decorator("$exceptionHandler", ['$delegate', function($delegate) 
        return function(exception, cause) 
            $delegate(exception, cause);
            alert(exception.message);
        ;
    ]);
);

它将执行原始异常处理程序所做的事情,以及自定义功能。

看到这个updated fiddle。

【讨论】:

对此+1 - 这是解决问题的更好方法。 使用了这个,但它似乎没有正确地进行缩小! 它是否可以像您在编辑中那样使用数组表示法?您必须在此处执行此操作,就像使用依赖注入进行缩小的其他任何地方一样。 @dnc253 是的,确实如此,我只是在弄清楚后才应用编辑。 我会建议注意:这可能会吞噬你的业力单元测试中的所有异常,这绝对不希望发生。【参考方案2】:

您可以通过创建同名服务来覆盖$exceptionHandler 功能:

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

mod.factory('$exceptionHandler', function () 
    return function (exception, cause) 
        alert(exception.message);
    ;
);

有关示例,请参阅 this fiddle。如果您注释掉 $exceptionHandler 的工厂定义,您将看到错误将记录到控制台而不是警告它。

这是一个group thread,它有一个使用$injector 注入其他服务的示例,例如$http

注意:如果您不想覆盖$exceptionHandler(或其他内置服务)的现有功能,请参阅this answer,了解有关如何装饰服务的信息。 p>

【讨论】:

那么,基本上你可以覆盖任何服务并且最后一个定义获胜,对吧? 比起这个,我更喜欢@dnc253 的解决方案。通过使用“装饰器”功能,您可以保留现有行为并允许其他装饰器参与操作。如果您出于不同的原因已经在其他地方这样做了,这将破坏已经存在的任何内容,包括您自己的代码。 我完全同意装饰器是一种更清洁的方法。 虽然装饰器看起来更好,但如果您想使用工厂或在 module.config 时未初始化的任何其他东西,这似乎是一个很好的解决方案 如果您在单独的包含模块中配置它,如果它是最后一个定义,这是否有效?【参考方案3】:

您可以覆盖任何服务/工厂,甚至 $cookieStore。如果您想要一个成熟的、可配置的对象,这里是 a really nice example:

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

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() 

    this.name = 'Default';

    this.$get = function() 
        var name = this.name;
        return 
            sayHello: function() 
                return "Hello, " + name + "!"
            
        
    ;

    this.setName = function(name) 
        this.name = name;
    ;
);

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider)
    helloWorldProvider.setName('World');
);


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) 

   helloWorld.sayHello(),

【讨论】:

以上是关于如何覆盖 $exceptionHandler 实现的主要内容,如果未能解决你的问题,请参考以下文章

Spring异常处理@ExceptionHandler

将 $http 注入 angular factory($exceptionHandler) 会导致循环依赖

在 micronaut 中覆盖未找到的异常处理程序

如何在@ExceptionHandler(Spring REST)中获取@RequestBody

springboot + @ControllerAdvice + @ExceptionHandler 实现全局异常拦截,不用

如何使用@ExceptionHandler 捕获 HTTP 405“不允许的方法”异常?