@@ -148,7 +148,6 @@ describe('event directives', function() {
148148 expect ( $rootScope . blur ) . toHaveBeenCalledOnce ( ) ;
149149 expect ( element . val ( ) ) . toBe ( 'newValue' ) ;
150150 } ) ) ;
151-
152151 } ) ;
153152
154153
@@ -190,4 +189,92 @@ describe('event directives', function() {
190189 expect ( $rootScope . click ) . toHaveBeenCalledOnce ( ) ;
191190 expect ( watchedVal ) . toEqual ( 'newValue' ) ;
192191 } ) ) ;
192+
193+
194+ describe ( 'throwing errors in event handlers' , function ( ) {
195+
196+ it ( 'should not stop execution if the event is triggered outside a digest' , function ( ) {
197+
198+ module ( function ( $exceptionHandlerProvider ) {
199+ $exceptionHandlerProvider . mode ( 'log' ) ;
200+ } ) ;
201+
202+ inject ( function ( $rootScope , $compile , $exceptionHandler , $log ) {
203+
204+ element = $compile ( '<button ng-click="click()">Click</button>' ) ( $rootScope ) ;
205+ expect ( $log . assertEmpty ( ) ) ;
206+ $rootScope . click = function ( ) {
207+ throw new Error ( 'listener error' ) ;
208+ } ;
209+
210+ $rootScope . do = function ( ) {
211+ element . triggerHandler ( 'click' ) ;
212+ $log . log ( 'done' ) ;
213+ } ;
214+
215+ $rootScope . do ( ) ;
216+
217+ expect ( $exceptionHandler . errors ) . toEqual ( [ Error ( 'listener error' ) ] ) ;
218+ expect ( $log . log . logs ) . toEqual ( [ [ 'done' ] ] ) ;
219+ $log . reset ( ) ;
220+ } ) ;
221+ } ) ;
222+
223+
224+ it ( 'should not stop execution if the event is triggered inside a digest' , function ( ) {
225+
226+ module ( function ( $exceptionHandlerProvider ) {
227+ $exceptionHandlerProvider . mode ( 'log' ) ;
228+ } ) ;
229+
230+ inject ( function ( $rootScope , $compile , $exceptionHandler , $log ) {
231+
232+ element = $compile ( '<button ng-click="click()">Click</button>' ) ( $rootScope ) ;
233+ expect ( $log . assertEmpty ( ) ) ;
234+ $rootScope . click = function ( ) {
235+ throw new Error ( 'listener error' ) ;
236+ } ;
237+
238+ $rootScope . do = function ( ) {
239+ element . triggerHandler ( 'click' ) ;
240+ $log . log ( 'done' ) ;
241+ } ;
242+
243+ $rootScope . $apply ( function ( ) {
244+ $rootScope . do ( ) ;
245+ } ) ;
246+
247+ expect ( $exceptionHandler . errors ) . toEqual ( [ Error ( 'listener error' ) ] ) ;
248+ expect ( $log . log . logs ) . toEqual ( [ [ 'done' ] ] ) ;
249+ $log . reset ( ) ;
250+ } ) ;
251+ } ) ;
252+
253+
254+ it ( 'should not stop execution if the event is triggered in a watch expression function' , function ( ) {
255+
256+ module ( function ( $exceptionHandlerProvider ) {
257+ $exceptionHandlerProvider . mode ( 'log' ) ;
258+ } ) ;
259+
260+ inject ( function ( $rootScope , $compile , $exceptionHandler , $log ) {
261+
262+ element = $compile ( '<button ng-click="click()">Click</button>' ) ( $rootScope ) ;
263+ $rootScope . click = function ( ) {
264+ throw new Error ( 'listener error' ) ;
265+ } ;
266+
267+ $rootScope . $watch ( function ( ) {
268+ element . triggerHandler ( 'click' ) ;
269+ $log . log ( 'done' ) ;
270+ } ) ;
271+
272+ $rootScope . $digest ( ) ;
273+
274+ expect ( $exceptionHandler . errors ) . toEqual ( [ Error ( 'listener error' ) , Error ( 'listener error' ) ] ) ;
275+ expect ( $log . log . logs ) . toEqual ( [ [ 'done' ] , [ 'done' ] ] ) ;
276+ $log . reset ( ) ;
277+ } ) ;
278+ } ) ;
279+ } ) ;
193280} ) ;
0 commit comments