@@ -24,6 +24,8 @@ import type { DataRouteMatch } from "../../context";
24
24
25
25
export const SingleFetchRedirectSymbol = Symbol ( "SingleFetchRedirect" ) ;
26
26
27
+ class SingleFetchNoResultError extends Error { }
28
+
27
29
export type SingleFetchRedirectResult = {
28
30
redirect : string ;
29
31
status : number ;
@@ -466,16 +468,29 @@ async function singleFetchLoaderNavigationStrategy(
466
468
467
469
await resolvePromise ;
468
470
469
- // Capture any middleware errors from routes that weren't actually fetching
470
- // data, these will be bubbled by the router in `processRouteLoaderData`
471
+ // If a middleware threw on the way down, we won't have data for our requested
472
+ // loaders and they'll resolve to `SingleFetchNoResultError` results. If this
473
+ // happens, take the highest error we find in our results (which is a middleware
474
+ // error if no loaders ever ran), and assign to these missing routes and let
475
+ // the router bubble accordingly
476
+ let middlewareError : unknown ;
471
477
let fetchedData = await singleFetchDfd . promise ;
472
478
if ( "routes" in fetchedData ) {
473
- Object . entries ( fetchedData . routes ) . forEach ( ( [ routeId , result ] ) => {
474
- if ( "error" in result && results [ routeId ] ?. type !== "error" ) {
475
- results [ routeId ] = {
476
- type : "error" ,
477
- result : result . error ,
478
- } ;
479
+ for ( let match of args . matches ) {
480
+ if ( match . route . id in fetchedData . routes ) {
481
+ let routeResult = fetchedData . routes [ match . route . id ] ;
482
+ if ( "error" in routeResult ) {
483
+ middlewareError = routeResult . error ;
484
+ break ;
485
+ }
486
+ }
487
+ }
488
+ }
489
+
490
+ if ( middlewareError !== undefined ) {
491
+ Array . from ( routesParams . values ( ) ) . forEach ( ( routeId ) => {
492
+ if ( results [ routeId ] . result instanceof SingleFetchNoResultError ) {
493
+ results [ routeId ] . result = middlewareError ;
479
494
}
480
495
} ) ;
481
496
}
@@ -709,7 +724,9 @@ function unwrapSingleFetchResult(
709
724
710
725
let routeResult = result . routes [ routeId ] ;
711
726
if ( routeResult == null ) {
712
- throw new Error ( `No result found for routeId "${ routeId } "` ) ;
727
+ throw new SingleFetchNoResultError (
728
+ `No result found for routeId "${ routeId } "`
729
+ ) ;
713
730
} else if ( "error" in routeResult ) {
714
731
throw routeResult . error ;
715
732
} else if ( "data" in routeResult ) {
0 commit comments