@@ -2491,6 +2491,85 @@ describe('Zone', function() {
24912491 expect ( logs ) . toEqual ( [ ] ) ;
24922492 } ) ) ;
24932493
2494+ it ( 'should re-throw the error when the only listener throw error' , function ( done : DoneFn ) {
2495+ // override global.onerror to prevent jasmine report error
2496+ let oriWindowOnError = window . onerror ;
2497+ let logs : string [ ] = [ ] ;
2498+ window . onerror = function ( err : any ) {
2499+ logs . push ( err ) ;
2500+ } ;
2501+ try {
2502+ const listener1 = function ( ) {
2503+ throw new Error ( 'test1' ) ;
2504+ } ;
2505+ button . addEventListener ( 'click' , listener1 ) ;
2506+
2507+ const mouseEvent = document . createEvent ( 'MouseEvent' ) ;
2508+ mouseEvent . initEvent ( 'click' , true , true ) ;
2509+
2510+ const unhandledRejection = ( e : PromiseRejectionEvent ) => {
2511+ fail ( 'should not be here' ) ;
2512+ } ;
2513+ window . addEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2514+
2515+ button . dispatchEvent ( mouseEvent ) ;
2516+ expect ( logs ) . toEqual ( [ 'Uncaught Error: test1' ] ) ;
2517+
2518+ setTimeout ( ( ) => {
2519+ expect ( logs ) . toEqual ( [ 'Uncaught Error: test1' ] ) ;
2520+ window . removeEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2521+ window . onerror = oriWindowOnError ;
2522+ done ( )
2523+ } ) ;
2524+ } catch ( e : any ) {
2525+ window . onerror = oriWindowOnError ;
2526+ }
2527+ } ) ;
2528+
2529+ it ( 'should not re-throw the error when zone onHandleError handled the error and the only listener throw error' ,
2530+ function ( done : DoneFn ) {
2531+ // override global.onerror to prevent jasmine report error
2532+ let oriWindowOnError = window . onerror ;
2533+ window . onerror = function ( ) { } ;
2534+ try {
2535+ let logs : string [ ] = [ ] ;
2536+ const listener1 = function ( ) {
2537+ throw new Error ( 'test1' ) ;
2538+ } ;
2539+ const zone = Zone . current . fork ( {
2540+ name : 'error' ,
2541+ onHandleError : ( delegate , curr , target , error ) => {
2542+ logs . push ( 'zone handled ' + target . name + ' ' + error . message ) ;
2543+ return false ;
2544+ }
2545+ } ) ;
2546+
2547+ zone . runGuarded ( ( ) => {
2548+ button . addEventListener ( 'click' , listener1 ) ;
2549+ } ) ;
2550+
2551+ const mouseEvent = document . createEvent ( 'MouseEvent' ) ;
2552+ mouseEvent . initEvent ( 'click' , true , true ) ;
2553+
2554+ const unhandledRejection = ( e : PromiseRejectionEvent ) => {
2555+ logs . push ( e . reason . message ) ;
2556+ } ;
2557+ window . addEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2558+
2559+ button . dispatchEvent ( mouseEvent ) ;
2560+ expect ( logs ) . toEqual ( [ 'zone handled error test1' ] ) ;
2561+
2562+ setTimeout ( ( ) => {
2563+ expect ( logs ) . toEqual ( [ 'zone handled error test1' ] ) ;
2564+ window . removeEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2565+ window . onerror = oriWindowOnError ;
2566+ done ( ) ;
2567+ } ) ;
2568+ } catch ( e : any ) {
2569+ window . onerror = oriWindowOnError ;
2570+ }
2571+ } ) ;
2572+
24942573 it ( 'should be able to continue to invoke remaining listeners even some listener throw error' ,
24952574 function ( done : DoneFn ) {
24962575 // override global.onerror to prevent jasmine report error
@@ -2540,13 +2619,77 @@ describe('Zone', function() {
25402619 }
25412620 } ) ;
25422621
2543- it ( 'should be able to continue to invoke remaining listeners even some listener throw error in the different zones ' ,
2622+ it ( 'should be able to continue to invoke remaining listeners even some listener throw error with onHandleError zone ' ,
25442623 function ( done : DoneFn ) {
25452624 // override global.onerror to prevent jasmine report error
25462625 let oriWindowOnError = window . onerror ;
25472626 window . onerror = function ( ) { } ;
25482627 try {
2628+ const zone = Zone . current . fork ( {
2629+ name : 'error' ,
2630+ onHandleError : ( delegate , curr , target , error ) => {
2631+ logs . push ( 'zone handled ' + target . name + ' ' + error . message ) ;
2632+ return false ;
2633+ }
2634+ } ) ;
25492635 let logs : string [ ] = [ ] ;
2636+ const listener1 = function ( ) {
2637+ logs . push ( 'listener1' ) ;
2638+ } ;
2639+ const listener2 = function ( ) {
2640+ throw new Error ( 'test1' ) ;
2641+ } ;
2642+ const listener3 = function ( ) {
2643+ throw new Error ( 'test2' ) ;
2644+ } ;
2645+ const listener4 = {
2646+ handleEvent : function ( ) {
2647+ logs . push ( 'listener2' ) ;
2648+ }
2649+ } ;
2650+
2651+ zone . runGuarded ( ( ) => {
2652+ button . addEventListener ( 'click' , listener1 ) ;
2653+ button . addEventListener ( 'click' , listener2 ) ;
2654+ button . addEventListener ( 'click' , listener3 ) ;
2655+ button . addEventListener ( 'click' , listener4 ) ;
2656+ } ) ;
2657+
2658+ const mouseEvent = document . createEvent ( 'MouseEvent' ) ;
2659+ mouseEvent . initEvent ( 'click' , true , true ) ;
2660+
2661+ const unhandledRejection = ( e : PromiseRejectionEvent ) => {
2662+ fail ( 'should not be here' ) ;
2663+ } ;
2664+ window . addEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2665+
2666+ button . dispatchEvent ( mouseEvent ) ;
2667+ expect ( logs ) . toEqual ( [
2668+ 'listener1' , 'zone handled error test1' , 'zone handled error test2' , 'listener2'
2669+ ] ) ;
2670+
2671+ setTimeout ( ( ) => {
2672+ expect ( logs ) . toEqual ( [
2673+ 'listener1' , 'zone handled error test1' , 'zone handled error test2' , 'listener2'
2674+ ] ) ;
2675+ window . removeEventListener ( 'unhandledrejection' , unhandledRejection ) ;
2676+ window . onerror = oriWindowOnError ;
2677+ done ( ) ;
2678+ } ) ;
2679+ } catch ( e : any ) {
2680+ window . onerror = oriWindowOnError ;
2681+ }
2682+ } ) ;
2683+
2684+ it ( 'should be able to continue to invoke remaining listeners even some listener throw error in the different zones' ,
2685+ function ( done : DoneFn ) {
2686+ // override global.onerror to prevent jasmine report error
2687+ let oriWindowOnError = window . onerror ;
2688+ let logs : string [ ] = [ ] ;
2689+ window . onerror = function ( err : any ) {
2690+ logs . push ( err ) ;
2691+ } ;
2692+ try {
25502693 const zone1 = Zone . current . fork ( {
25512694 name : 'zone1' ,
25522695 onHandleError : ( delegate , curr , target , error ) => {
@@ -2580,18 +2723,18 @@ describe('Zone', function() {
25802723 mouseEvent . initEvent ( 'click' , true , true ) ;
25812724
25822725 const unhandledRejection = ( e : PromiseRejectionEvent ) => {
2583- logs . push ( e . reason . message ) ;
2726+ fail ( 'should not be here' ) ;
25842727 } ;
25852728 window . addEventListener ( 'unhandledrejection' , unhandledRejection ) ;
25862729
25872730 button . dispatchEvent ( mouseEvent ) ;
2588- expect ( logs ) . toEqual ( [ 'listener1' , 'test1' , 'listener2' ] ) ;
2731+ expect ( logs ) . toEqual ( [ 'listener1' , 'test1' , 'listener2' , 'Uncaught Error: test2' ] ) ;
25892732
25902733 setTimeout ( ( ) => {
2591- expect ( logs ) . toEqual ( [ 'listener1' , 'test1' , 'listener2' , 'test2' ] ) ;
2734+ expect ( logs ) . toEqual ( [ 'listener1' , 'test1' , 'listener2' , 'Uncaught Error: test2' ] ) ;
25922735 window . removeEventListener ( 'unhandledrejection' , unhandledRejection ) ;
25932736 window . onerror = oriWindowOnError ;
2594- done ( )
2737+ done ( ) ;
25952738 } ) ;
25962739 } catch ( e : any ) {
25972740 window . onerror = oriWindowOnError ;
0 commit comments