Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当装饰angulars$exceptionHandler时,如何防止令人讨厌的副作用?_Javascript_Angularjs_Jasmine_Karma Runner - Fatal编程技术网

Javascript 当装饰angulars$exceptionHandler时,如何防止令人讨厌的副作用?

Javascript 当装饰angulars$exceptionHandler时,如何防止令人讨厌的副作用?,javascript,angularjs,jasmine,karma-runner,Javascript,Angularjs,Jasmine,Karma Runner,对于自定义服务器端日志记录,我正在包装angulars$exceptionHandler,就像在许多地方描述的那样,包括stackoverflow和angular文档(有一些变体,但它们基本上做相同的事情): 然而,这导致$exceptionHandler在karma/jasmine单元测试期间不会抛出任何错误 这可以通过使用来解释,当模块未装饰时,它可以正常运行,但当模块为: beforeEach(module('logging')); describe('$exceptionHandler

对于自定义服务器端日志记录,我正在包装angulars$exceptionHandler,就像在许多地方描述的那样,包括stackoverflow和angular文档(有一些变体,但它们基本上做相同的事情):

然而,这导致$exceptionHandler在karma/jasmine单元测试期间不会抛出任何错误

这可以通过使用来解释,当模块未装饰时,它可以正常运行,但当模块为:

beforeEach(module('logging'));

describe('$exceptionHandlerProvider', function () {
    // testing standard behaviour of $exceptionHandler
    // see https://docs.angularjs.org/api/ngMock/service/$exceptionHandler
    it('should capture log messages and exceptions', function () {
        module(function ($exceptionHandlerProvider) {
            $exceptionHandlerProvider.mode('log');
        });

        inject(function ($log, $exceptionHandler, $timeout) {
            $timeout(function () {
                $log.log(1);
            });
            $timeout(function () {
                $log.log(2);
                throw 'banana peel';
            });
            $timeout(function () {
                $log.log(3);
            });
            expect($exceptionHandler.errors).toEqual([]);
            expect($log.assertEmpty());
            $timeout.flush();
            expect($exceptionHandler.errors).toEqual(['banana peel']);
            expect($log.log.logs).toEqual([[1], [2], [3]]);
        });
    });
});
知道如何纠正这种行为吗?还有


我正在使用angular#1.3.14

来自
ngMock
$exceptionHandler
函数具有指向数组的
error
属性

装饰程序返回的函数没有该属性:

return function () {

  ExceptionLoggingService.apply(null, arguments);

  $delegate.apply(null, arguments);
};
例如,这将失败:

expect($exceptionHandler.errors).toEqual([]);
下面是一个有望奏效的实现:

app.config(function($provide) {
  $provide.decorator('$exceptionHandler', ['$delegate', 'ExceptionLoggingService',
    function($delegate, ExceptionLoggingService) {

      var decoratedExceptionHandler = function() {

        ExceptionLoggingService.apply(this, arguments);

        return $delegate.apply(this, arguments);
      };

      for (var key in $delegate) {

        if (!$delegate.hasOwnProperty(key)) continue;

        decoratedExceptionHandler[key] = $delegate[key];
      }

      return decoratedExceptionHandler;    
    }
  ]);
});

作为一个注意事项,你应该始终确保这样做时,装饰。
$exceptionHandler
的实际实现现在可能没有任何属性,但您永远不知道将来是否会有属性。
$templateRequest
服务是您必须执行此操作的一个示例,因为它的属性在内部用于使视图动画工作。

非常感谢您的出色回答。还有一个小问题。我得到的错误“预期[[1],[2],[TypeError:“undefined”不是一个对象(计算'e.stack.split'),[3]]等于[[1],[2],[3].”我将尝试解决它。没问题:)我刚刚尝试过,它对我有效。您能在Plunk中复制它吗?您能在不调用
例外记录服务的情况下尝试吗?我不知道你的实现是什么样子的,只是在测试时使用了一个虚拟的。如果我完全忽略它,这没有什么区别。我创建了一个plunkr,奇怪的是它让其他条件失败,而不是我本地测试中的条件:Remove
var args=[].slice.call(arguments)
并将
参数
传递给
$delegate。改为应用
app.config(function($provide) {
  $provide.decorator('$exceptionHandler', ['$delegate', 'ExceptionLoggingService',
    function($delegate, ExceptionLoggingService) {

      var decoratedExceptionHandler = function() {

        ExceptionLoggingService.apply(this, arguments);

        return $delegate.apply(this, arguments);
      };

      for (var key in $delegate) {

        if (!$delegate.hasOwnProperty(key)) continue;

        decoratedExceptionHandler[key] = $delegate[key];
      }

      return decoratedExceptionHandler;    
    }
  ]);
});