@@ -48,15 +48,15 @@ function mockedLoader<T = string | NavigationResult>(
48
48
describe ( 'navigation-guard' , ( ) => {
49
49
let globalApp : App | undefined
50
50
51
- function setupApp ( { isSSR } : Omit < DataLoaderPluginOptions , 'router' > ) {
51
+ function setupApp ( options : Omit < DataLoaderPluginOptions , 'router' > ) {
52
52
const app = createApp ( { render : ( ) => null } )
53
53
const selectNavigationResult = vi
54
54
. fn ( )
55
55
. mockImplementation ( ( results ) => results [ 0 ] . value )
56
56
app . use ( DataLoaderPlugin , {
57
57
router : getRouter ( ) ,
58
58
selectNavigationResult,
59
- isSSR ,
59
+ ... options ,
60
60
} )
61
61
// invalidate current context
62
62
setCurrentContext ( undefined )
@@ -544,5 +544,68 @@ describe('navigation-guard', () => {
544
544
await router . getPendingNavigation ( )
545
545
expect ( router . currentRoute . value . fullPath ) . not . toBe ( '/fetch' )
546
546
} )
547
+
548
+ it ( 'local errors take precedence over global errors' , async ( ) => {
549
+ setupApp ( {
550
+ isSSR : false ,
551
+ // global only accepts CustomError
552
+ errors : ( e ) => e instanceof CustomError ,
553
+ } )
554
+ const router = getRouter ( )
555
+ const l1 = mockedLoader ( {
556
+ // but local accepts Error with message 'expected'
557
+ errors : ( e ) => e instanceof Error && e . message === 'expected' ,
558
+ } )
559
+ router . addRoute ( {
560
+ name : '_test' ,
561
+ path : '/fetch' ,
562
+ component,
563
+ meta : {
564
+ loaders : [ l1 . loader ] ,
565
+ } ,
566
+ } )
567
+
568
+ // not covered by any
569
+ router . push ( '/fetch' )
570
+ await vi . runOnlyPendingTimersAsync ( )
571
+ l1 . reject ( new Error ( 'unexpected' ) )
572
+ await router . getPendingNavigation ( ) . catch ( ( ) => { } )
573
+ expect ( router . currentRoute . value . fullPath ) . not . toBe ( '/fetch' )
574
+
575
+ // covered locally only
576
+ router . push ( '/fetch' )
577
+ await vi . runOnlyPendingTimersAsync ( )
578
+ l1 . reject ( new Error ( 'expected' ) )
579
+ await router . getPendingNavigation ( ) . catch ( ( ) => { } )
580
+ expect ( router . currentRoute . value . fullPath ) . toBe ( '/fetch' )
581
+ } )
582
+
583
+ it ( 'handle global expected errors even when rejected by local errors' , async ( ) => {
584
+ setupApp ( {
585
+ isSSR : false ,
586
+ // global only accepts CustomError
587
+ errors : [ CustomError ] ,
588
+ } )
589
+ const router = getRouter ( )
590
+ const l1 = mockedLoader ( {
591
+ // but local accepts Error with message 'expected'
592
+ errors : ( e ) => e instanceof Error && e . message === 'expected' ,
593
+ } )
594
+ router . addRoute ( {
595
+ name : '_test' ,
596
+ path : '/fetch' ,
597
+ component,
598
+ meta : {
599
+ loaders : [ l1 . loader ] ,
600
+ } ,
601
+ } )
602
+ //
603
+ // covered locally only
604
+ router . push ( '/fetch' )
605
+ await vi . runOnlyPendingTimersAsync ( )
606
+ l1 . reject ( new CustomError ( ) )
607
+ await router . getPendingNavigation ( ) . catch ( ( ) => { } )
608
+ expect ( router . currentRoute . value . fullPath ) . toBe ( '/fetch' )
609
+ } )
547
610
} )
548
611
} )
0 commit comments