fix(ngEventDirs): pass error in handler to $exceptionHandler when event was triggered in a digest
This ensures that the error handling is the same for events triggered inside and outside a digest.
This commit is contained in:
committed by
Martin Staffa
parent
6b0193e4d9
commit
a42f8a0d5b
@@ -50,7 +50,7 @@ forEach(
|
||||
'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
|
||||
function(eventName) {
|
||||
var directiveName = directiveNormalize('ng-' + eventName);
|
||||
ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
|
||||
ngEventDirectives[directiveName] = ['$parse', '$rootScope', '$exceptionHandler', function($parse, $rootScope, $exceptionHandler) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, attr) {
|
||||
@@ -64,12 +64,17 @@ forEach(
|
||||
var callback = function() {
|
||||
fn(scope, {$event: event});
|
||||
};
|
||||
|
||||
if (!$rootScope.$$phase) {
|
||||
scope.$apply(callback);
|
||||
} else if (forceAsyncEvents[eventName]) {
|
||||
scope.$evalAsync(callback);
|
||||
} else {
|
||||
callback();
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
$exceptionHandler(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -148,7 +148,6 @@ describe('event directives', function() {
|
||||
expect($rootScope.blur).toHaveBeenCalledOnce();
|
||||
expect(element.val()).toBe('newValue');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -190,4 +189,92 @@ describe('event directives', function() {
|
||||
expect($rootScope.click).toHaveBeenCalledOnce();
|
||||
expect(watchedVal).toEqual('newValue');
|
||||
}));
|
||||
|
||||
|
||||
describe('throwing errors in event handlers', function() {
|
||||
|
||||
it('should not stop execution if the event is triggered outside a digest', function() {
|
||||
|
||||
module(function($exceptionHandlerProvider) {
|
||||
$exceptionHandlerProvider.mode('log');
|
||||
});
|
||||
|
||||
inject(function($rootScope, $compile, $exceptionHandler, $log) {
|
||||
|
||||
element = $compile('<button ng-click="click()">Click</button>')($rootScope);
|
||||
expect($log.assertEmpty());
|
||||
$rootScope.click = function() {
|
||||
throw new Error('listener error');
|
||||
};
|
||||
|
||||
$rootScope.do = function() {
|
||||
element.triggerHandler('click');
|
||||
$log.log('done');
|
||||
};
|
||||
|
||||
$rootScope.do();
|
||||
|
||||
expect($exceptionHandler.errors).toEqual([Error('listener error')]);
|
||||
expect($log.log.logs).toEqual([['done']]);
|
||||
$log.reset();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should not stop execution if the event is triggered inside a digest', function() {
|
||||
|
||||
module(function($exceptionHandlerProvider) {
|
||||
$exceptionHandlerProvider.mode('log');
|
||||
});
|
||||
|
||||
inject(function($rootScope, $compile, $exceptionHandler, $log) {
|
||||
|
||||
element = $compile('<button ng-click="click()">Click</button>')($rootScope);
|
||||
expect($log.assertEmpty());
|
||||
$rootScope.click = function() {
|
||||
throw new Error('listener error');
|
||||
};
|
||||
|
||||
$rootScope.do = function() {
|
||||
element.triggerHandler('click');
|
||||
$log.log('done');
|
||||
};
|
||||
|
||||
$rootScope.$apply(function() {
|
||||
$rootScope.do();
|
||||
});
|
||||
|
||||
expect($exceptionHandler.errors).toEqual([Error('listener error')]);
|
||||
expect($log.log.logs).toEqual([['done']]);
|
||||
$log.reset();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should not stop execution if the event is triggered in a watch expression function', function() {
|
||||
|
||||
module(function($exceptionHandlerProvider) {
|
||||
$exceptionHandlerProvider.mode('log');
|
||||
});
|
||||
|
||||
inject(function($rootScope, $compile, $exceptionHandler, $log) {
|
||||
|
||||
element = $compile('<button ng-click="click()">Click</button>')($rootScope);
|
||||
$rootScope.click = function() {
|
||||
throw new Error('listener error');
|
||||
};
|
||||
|
||||
$rootScope.$watch(function() {
|
||||
element.triggerHandler('click');
|
||||
$log.log('done');
|
||||
});
|
||||
|
||||
$rootScope.$digest();
|
||||
|
||||
expect($exceptionHandler.errors).toEqual([Error('listener error'), Error('listener error')]);
|
||||
expect($log.log.logs).toEqual([['done'], ['done']]);
|
||||
$log.reset();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user