@@ -3525,9 +3525,9 @@ export function createStaticHandler(
3525
3525
3526
3526
return res ;
3527
3527
} ,
3528
- async ( e ) => {
3529
- if ( isResponse ( e . error ) ) {
3530
- return e . error ;
3528
+ async ( error , routeId ) => {
3529
+ if ( isResponse ( error ) ) {
3530
+ return error ;
3531
3531
}
3532
3532
3533
3533
if ( renderedStaticContext ) {
@@ -3538,16 +3538,16 @@ export function createStaticHandler(
3538
3538
// to align server/client behavior. Client side middleware uses
3539
3539
// dataStrategy and a given route can only have one result, so the
3540
3540
// error overwrites any prior loader data.
3541
- if ( e . routeId in renderedStaticContext . loaderData ) {
3542
- renderedStaticContext . loaderData [ e . routeId ] = undefined ;
3541
+ if ( routeId in renderedStaticContext . loaderData ) {
3542
+ renderedStaticContext . loaderData [ routeId ] = undefined ;
3543
3543
}
3544
3544
3545
3545
return respond (
3546
3546
getStaticContextFromError (
3547
3547
dataRoutes ,
3548
3548
renderedStaticContext ,
3549
- e . error ,
3550
- findNearestBoundary ( matches ! , e . routeId ) . route . id
3549
+ error ,
3550
+ findNearestBoundary ( matches ! , routeId ) . route . id
3551
3551
)
3552
3552
) ;
3553
3553
} else {
@@ -3568,11 +3568,9 @@ export function createStaticHandler(
3568
3568
loaderData : { } ,
3569
3569
actionData : null ,
3570
3570
errors : {
3571
- [ boundary . route . id ] : e . error ,
3571
+ [ boundary . route . id ] : error ,
3572
3572
} ,
3573
- statusCode : isRouteErrorResponse ( e . error )
3574
- ? e . error . status
3575
- : 500 ,
3573
+ statusCode : isRouteErrorResponse ( error ) ? error . status : 500 ,
3576
3574
actionHeaders : { } ,
3577
3575
loaderHeaders : { } ,
3578
3576
} ) ;
@@ -3731,11 +3729,11 @@ export function createStaticHandler(
3731
3729
? new Response ( value )
3732
3730
: Response . json ( value ) ;
3733
3731
} ,
3734
- ( e ) => {
3735
- if ( isResponse ( e . error ) ) {
3736
- return respond ( e . error ) ;
3732
+ ( error ) => {
3733
+ if ( isResponse ( error ) ) {
3734
+ return respond ( error ) ;
3737
3735
}
3738
- return new Response ( String ( e . error ) , {
3736
+ return new Response ( String ( error ) , {
3739
3737
status : 500 ,
3740
3738
statusText : "Unexpected Server Error" ,
3741
3739
} ) ;
@@ -4935,13 +4933,21 @@ async function defaultDataStrategyWithMiddleware(
4935
4933
args ,
4936
4934
false ,
4937
4935
( ) => defaultDataStrategy ( args ) ,
4938
- ( e ) => ( { [ e . routeId ] : { type : "error" , result : e . error } } )
4936
+ ( error , routeId ) => ( { [ routeId ] : { type : "error" , result : error } } )
4939
4937
) as Promise < Record < string , DataStrategyResult > > ;
4940
4938
}
4941
4939
4942
4940
type MutableMiddlewareState = {
4943
- handlerResult : unknown ;
4944
- propagateResult : boolean ;
4941
+ // Track the result of the user-provided handler at the bottom of the
4942
+ // middleware chain so we can return it out from runMiddleware for them when
4943
+ // we're not propagating results
4944
+ handlerResult ?: unknown ;
4945
+ // Capture the throwing routeId for middleware error so we can bubble from the
4946
+ // correct spot
4947
+ middlewareError ?: {
4948
+ routeId : string ;
4949
+ error : unknown ;
4950
+ } ;
4945
4951
} ;
4946
4952
4947
4953
export async function runMiddlewarePipeline < T extends boolean > (
@@ -4957,12 +4963,11 @@ export async function runMiddlewarePipeline<T extends boolean>(
4957
4963
handler : ( ) => T extends true
4958
4964
? MaybePromise < Response >
4959
4965
: MaybePromise < Record < string , DataStrategyResult > > ,
4960
- errorHandler : ( error : MiddlewareError ) => unknown
4966
+ errorHandler : ( error : unknown , routeId : string ) => unknown
4961
4967
) : Promise < unknown > {
4962
4968
let { matches, request, params, context } = args ;
4963
4969
let middlewareState : MutableMiddlewareState = {
4964
4970
handlerResult : undefined ,
4965
- propagateResult,
4966
4971
} ;
4967
4972
try {
4968
4973
let tuples = matches . flatMap ( ( m ) =>
@@ -4973,40 +4978,34 @@ export async function runMiddlewarePipeline<T extends boolean>(
4973
4978
let result = await callRouteMiddleware (
4974
4979
{ request, params, context } ,
4975
4980
tuples ,
4981
+ propagateResult ,
4976
4982
middlewareState ,
4977
4983
handler
4978
4984
) ;
4979
- return middlewareState . propagateResult
4980
- ? result
4981
- : middlewareState . handlerResult ;
4985
+ return propagateResult ? result : middlewareState . handlerResult ;
4982
4986
} catch ( e ) {
4983
- if ( ! ( e instanceof MiddlewareError ) ) {
4987
+ if ( ! middlewareState . middlewareError ) {
4984
4988
// This shouldn't happen? This would have to come from a bug in our
4985
4989
// library code...
4986
4990
throw e ;
4987
4991
}
4988
- let result = await errorHandler ( e ) ;
4992
+ let result = await errorHandler (
4993
+ middlewareState . middlewareError . error ,
4994
+ middlewareState . middlewareError . routeId
4995
+ ) ;
4989
4996
if ( propagateResult || ! middlewareState . handlerResult ) {
4990
4997
return result ;
4991
4998
}
4992
4999
return Object . assign ( middlewareState . handlerResult , result ) ;
4993
5000
}
4994
5001
}
4995
5002
4996
- export class MiddlewareError {
4997
- routeId : string ;
4998
- error : unknown ;
4999
- constructor ( routeId : string , error : unknown ) {
5000
- this . routeId = routeId ;
5001
- this . error = error ;
5002
- }
5003
- }
5004
-
5005
5003
async function callRouteMiddleware (
5006
5004
args :
5007
5005
| LoaderFunctionArgs < unstable_RouterContextProvider >
5008
5006
| ActionFunctionArgs < unstable_RouterContextProvider > ,
5009
5007
middlewares : [ string , unstable_MiddlewareFunction ] [ ] ,
5008
+ propagateResult : boolean ,
5010
5009
middlewareState : MutableMiddlewareState ,
5011
5010
handler : ( ) => void ,
5012
5011
idx = 0
@@ -5039,11 +5038,12 @@ async function callRouteMiddleware(
5039
5038
let result = await callRouteMiddleware (
5040
5039
args ,
5041
5040
middlewares ,
5041
+ propagateResult ,
5042
5042
middlewareState ,
5043
5043
handler ,
5044
5044
idx + 1
5045
5045
) ;
5046
- if ( middlewareState . propagateResult ) {
5046
+ if ( propagateResult ) {
5047
5047
nextResult = result ;
5048
5048
return nextResult ;
5049
5049
}
@@ -5070,11 +5070,15 @@ async function callRouteMiddleware(
5070
5070
} else {
5071
5071
return next ( ) ;
5072
5072
}
5073
- } catch ( e ) {
5074
- if ( e instanceof MiddlewareError ) {
5075
- throw e ;
5073
+ } catch ( error ) {
5074
+ if ( ! middlewareState . middlewareError ) {
5075
+ middlewareState . middlewareError = { routeId, error } ;
5076
+ } else if ( middlewareState . middlewareError . error !== error ) {
5077
+ // Another middleware already threw, so only capture this new routeId if
5078
+ // it's a different error and not just bubbling up the existing error
5079
+ middlewareState . middlewareError = { routeId, error } ;
5076
5080
}
5077
- throw new MiddlewareError ( routeId , e ) ;
5081
+ throw error ;
5078
5082
}
5079
5083
}
5080
5084
0 commit comments