Skip to content

Commit 974b5c3

Browse files
authored
fix(router-core): forward notFound/redirect from params.parse correctly (#5864)
1 parent 04f701f commit 974b5c3

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

packages/router-core/src/router.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,7 @@ export class RouterCore<
13881388

13891389
const strictParams = existingMatch?._strictParams ?? usedParams
13901390

1391-
let paramsError: PathParamError | undefined = undefined
1391+
let paramsError: unknown = undefined
13921392

13931393
if (!existingMatch) {
13941394
const strictParseParams =
@@ -1401,9 +1401,13 @@ export class RouterCore<
14011401
strictParseParams(strictParams as Record<string, string>),
14021402
)
14031403
} catch (err: any) {
1404-
paramsError = new PathParamError(err.message, {
1405-
cause: err,
1406-
})
1404+
if (isNotFound(err) || isRedirect(err)) {
1405+
paramsError = err
1406+
} else {
1407+
paramsError = new PathParamError(err.message, {
1408+
cause: err,
1409+
})
1410+
}
14071411

14081412
if (opts?.throwOnError) {
14091413
throw paramsError

packages/router-core/tests/load.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,66 @@ test('cancelMatches after pending timeout', async () => {
509509
expect(cancelledFooMatch?._nonReactive.pendingTimeout).toBeUndefined()
510510
})
511511

512+
describe('params.parse notFound', () => {
513+
test('throws notFound on invalid params', async () => {
514+
const rootRoute = new BaseRootRoute({})
515+
const testRoute = new BaseRoute({
516+
getParentRoute: () => rootRoute,
517+
path: '/test/$id',
518+
params: {
519+
parse: ({ id }: { id: string }) => {
520+
const parsed = parseInt(id, 10)
521+
if (Number.isNaN(parsed)) {
522+
throw notFound()
523+
}
524+
return { id: parsed }
525+
},
526+
},
527+
})
528+
const routeTree = rootRoute.addChildren([testRoute])
529+
const router = new RouterCore({
530+
routeTree,
531+
history: createMemoryHistory({ initialEntries: ['/test/invalid'] }),
532+
})
533+
534+
await router.load()
535+
536+
const match = router.state.pendingMatches?.find(
537+
(m) => m.routeId === testRoute.id,
538+
)
539+
540+
expect(match?.status).toBe('notFound')
541+
})
542+
543+
test('succeeds on valid params', async () => {
544+
const rootRoute = new BaseRootRoute({})
545+
const testRoute = new BaseRoute({
546+
getParentRoute: () => rootRoute,
547+
path: '/test/$id',
548+
params: {
549+
parse: ({ id }: { id: string }) => {
550+
const parsed = parseInt(id, 10)
551+
if (Number.isNaN(parsed)) {
552+
throw notFound()
553+
}
554+
return { id: parsed }
555+
},
556+
},
557+
})
558+
const routeTree = rootRoute.addChildren([testRoute])
559+
const router = new RouterCore({
560+
routeTree,
561+
history: createMemoryHistory({ initialEntries: ['/test/123'] }),
562+
})
563+
564+
await router.load()
565+
566+
const match = router.state.matches.find((m) => m.routeId === testRoute.id)
567+
expect(match?.status).toBe('success')
568+
expect(router.state.statusCode).toBe(200)
569+
})
570+
})
571+
512572
function sleep(ms: number) {
513573
return new Promise<void>((resolve) => setTimeout(resolve, ms))
514574
}

0 commit comments

Comments
 (0)