Skip to content

Commit 6a2f555

Browse files
authored
refactor: move redirect helpers into separate module (#73118)
1 parent e1b23eb commit 6a2f555

File tree

12 files changed

+71
-65
lines changed

12 files changed

+71
-65
lines changed

packages/next/src/client/components/app-router.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,8 @@ import { useNavFailureHandler } from './nav-failure-handler'
5555
import { useServerActionDispatcher } from '../app-call-server'
5656
import type { AppRouterActionQueue } from '../../shared/lib/router/action-queue'
5757
import { prefetch as prefetchWithSegmentCache } from '../components/segment-cache/prefetch'
58-
59-
import {
60-
getRedirectTypeFromError,
61-
getURLFromRedirectError,
62-
isRedirectError,
63-
RedirectType,
64-
} from './redirect'
58+
import { getRedirectTypeFromError, getURLFromRedirectError } from './redirect'
59+
import { isRedirectError, RedirectType } from './redirect-error'
6560

6661
const globalMutable: {
6762
pendingMpaPath?: string

packages/next/src/client/components/is-next-router-error.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
isHTTPAccessFallbackError,
33
type HTTPAccessFallbackError,
44
} from './http-access-fallback/http-access-fallback'
5-
import { isRedirectError, type RedirectError } from './redirect'
5+
import { isRedirectError, type RedirectError } from './redirect-error'
66

77
/**
88
* Returns true if the error is a navigation signal error. These errors are

packages/next/src/client/components/navigation.react-server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class ReadonlyURLSearchParams extends URLSearchParams {
2626
}
2727
}
2828

29-
export { redirect, permanentRedirect, RedirectType } from './redirect'
29+
export { redirect, permanentRedirect } from './redirect'
30+
export { RedirectType } from './redirect-error'
3031
export { notFound } from './not-found'
3132
export { forbidden } from './forbidden'
3233
export { unauthorized } from './unauthorized'

packages/next/src/client/components/redirect-boundary.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22
import React, { useEffect } from 'react'
33
import type { AppRouterInstance } from '../../shared/lib/app-router-context.shared-runtime'
44
import { useRouter } from './navigation'
5-
import {
6-
RedirectType,
7-
getRedirectTypeFromError,
8-
getURLFromRedirectError,
9-
isRedirectError,
10-
} from './redirect'
5+
import { getRedirectTypeFromError, getURLFromRedirectError } from './redirect'
6+
import { RedirectType, isRedirectError } from './redirect-error'
117

128
interface RedirectBoundaryProps {
139
router: AppRouterInstance
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { RedirectStatusCode } from './redirect-status-code'
2+
3+
export const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT'
4+
5+
export enum RedirectType {
6+
push = 'push',
7+
replace = 'replace',
8+
}
9+
10+
export type RedirectError = Error & {
11+
digest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${string};${RedirectStatusCode};`
12+
}
13+
14+
/**
15+
* Checks an error to determine if it's an error generated by the
16+
* `redirect(url)` helper.
17+
*
18+
* @param error the error that may reference a redirect error
19+
* @returns true if the error is a redirect error
20+
*/
21+
export function isRedirectError(error: unknown): error is RedirectError {
22+
if (
23+
typeof error !== 'object' ||
24+
error === null ||
25+
!('digest' in error) ||
26+
typeof error.digest !== 'string'
27+
) {
28+
return false
29+
}
30+
31+
const digest = error.digest.split(';')
32+
const [errorCode, type] = digest
33+
const destination = digest.slice(2, -2).join(';')
34+
const status = digest.at(-2)
35+
36+
const statusCode = Number(status)
37+
38+
return (
39+
errorCode === REDIRECT_ERROR_CODE &&
40+
(type === 'replace' || type === 'push') &&
41+
typeof destination === 'string' &&
42+
!isNaN(statusCode) &&
43+
statusCode in RedirectStatusCode
44+
)
45+
}

packages/next/src/client/components/redirect.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import { getURLFromRedirectError, isRedirectError, redirect } from './redirect'
1+
import { getURLFromRedirectError, redirect } from './redirect'
2+
import { isRedirectError } from './redirect-error'
3+
24
describe('test', () => {
35
it('should throw a redirect error', () => {
46
try {

packages/next/src/client/components/redirect.ts

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import { actionAsyncStorage } from '../../server/app-render/action-async-storage.external'
22
import { RedirectStatusCode } from './redirect-status-code'
3-
4-
const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT'
5-
6-
export enum RedirectType {
7-
push = 'push',
8-
replace = 'replace',
9-
}
10-
11-
export type RedirectError = Error & {
12-
digest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${string};${RedirectStatusCode};`
13-
}
3+
import {
4+
RedirectType,
5+
type RedirectError,
6+
isRedirectError,
7+
REDIRECT_ERROR_CODE,
8+
} from './redirect-error'
149

1510
export function getRedirectError(
1611
url: string,
@@ -68,39 +63,6 @@ export function permanentRedirect(
6863
throw getRedirectError(url, type, RedirectStatusCode.PermanentRedirect)
6964
}
7065

71-
/**
72-
* Checks an error to determine if it's an error generated by the
73-
* `redirect(url)` helper.
74-
*
75-
* @param error the error that may reference a redirect error
76-
* @returns true if the error is a redirect error
77-
*/
78-
export function isRedirectError(error: unknown): error is RedirectError {
79-
if (
80-
typeof error !== 'object' ||
81-
error === null ||
82-
!('digest' in error) ||
83-
typeof error.digest !== 'string'
84-
) {
85-
return false
86-
}
87-
88-
const digest = error.digest.split(';')
89-
const [errorCode, type] = digest
90-
const destination = digest.slice(2, -2).join(';')
91-
const status = digest.at(-2)
92-
93-
const statusCode = Number(status)
94-
95-
return (
96-
errorCode === REDIRECT_ERROR_CODE &&
97-
(type === 'replace' || type === 'push') &&
98-
typeof destination === 'string' &&
99-
!isNaN(statusCode) &&
100-
statusCode in RedirectStatusCode
101-
)
102-
}
103-
10466
/**
10567
* Returns the encoded URL from the error if it's a RedirectError, null
10668
* otherwise. Note that this does not validate the URL returned.

packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ import {
4747
normalizeFlightData,
4848
type NormalizedFlightData,
4949
} from '../../../flight-data-helpers'
50-
import { getRedirectError, RedirectType } from '../../redirect'
50+
import { getRedirectError } from '../../redirect'
51+
import { RedirectType } from '../../redirect-error'
5152
import { createSeededPrefetchCacheEntry } from '../prefetch-cache-utils'
5253
import { removeBasePath } from '../../../remove-base-path'
5354
import { hasBasePath } from '../../../has-base-path'

packages/next/src/server/app-render/action-handler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ import {
1818
import {
1919
getRedirectTypeFromError,
2020
getURLFromRedirectError,
21+
} from '../../client/components/redirect'
22+
import {
2123
isRedirectError,
2224
type RedirectType,
23-
} from '../../client/components/redirect'
25+
} from '../../client/components/redirect-error'
2426
import RenderResult from '../render-result'
2527
import type { WorkStore } from '../app-render/work-async-storage.external'
2628
import { FlightRenderResult } from './flight-render-result'

packages/next/src/server/app-render/app-render.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ import {
6666
} from '../../client/components/http-access-fallback/http-access-fallback'
6767
import {
6868
getURLFromRedirectError,
69-
isRedirectError,
7069
getRedirectStatusCodeFromError,
7170
} from '../../client/components/redirect'
71+
import { isRedirectError } from '../../client/components/redirect-error'
7272
import { getImplicitTags } from '../lib/implicit-tags'
7373
import { AppRenderSpan, NextNodeServerSpan } from '../lib/trace/constants'
7474
import { getTracer } from '../lib/trace/tracer'

0 commit comments

Comments
 (0)