Skip to content

Commit

Permalink
Update handling of redirect/404 throw to cross server->client boundary (
Browse files Browse the repository at this point in the history
  • Loading branch information
timneutkens committed Sep 26, 2022
1 parent 3211b3f commit 8b802dd
Show file tree
Hide file tree
Showing 6 changed files with 16 additions and 31 deletions.
7 changes: 4 additions & 3 deletions packages/next/client/components/layout-router.client.tsx
Expand Up @@ -309,8 +309,9 @@ class RedirectErrorBoundary extends React.Component<
}

static getDerivedStateFromError(error: any) {
if (error.digest === 'NEXT_REDIRECT') {
return { redirect: error.url }
if (error.digest?.startsWith('NEXT_REDIRECT')) {
const url = error.digest.split(';')[1]
return { redirect: url }
}
// Re-throw if error is not for 404
throw error
Expand Down Expand Up @@ -354,7 +355,7 @@ class NotFoundErrorBoundary extends React.Component<
}

static getDerivedStateFromError(error: any) {
if (error.code === 'NEXT_NOT_FOUND') {
if (error.digest === 'NEXT_NOT_FOUND') {
return { notFoundTriggered: true }
}
// Re-throw if error is not for 404
Expand Down
6 changes: 3 additions & 3 deletions packages/next/client/components/not-found.ts
Expand Up @@ -2,7 +2,7 @@ export const NOT_FOUND_ERROR_CODE = 'NEXT_NOT_FOUND'

export function notFound() {
// eslint-disable-next-line no-throw-literal
throw {
code: NOT_FOUND_ERROR_CODE,
}
const error = new Error(NOT_FOUND_ERROR_CODE)
;(error as any).digest = NOT_FOUND_ERROR_CODE
throw error
}
3 changes: 1 addition & 2 deletions packages/next/client/components/redirect.ts
Expand Up @@ -3,7 +3,6 @@ export const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT'
export function redirect(url: string) {
// eslint-disable-next-line no-throw-literal
const error = new Error(REDIRECT_ERROR_CODE)
;(error as any).url = url
;(error as any).digest = REDIRECT_ERROR_CODE
;(error as any).digest = REDIRECT_ERROR_CODE + ';' + url
throw error
}
4 changes: 3 additions & 1 deletion packages/next/export/worker.ts
Expand Up @@ -30,6 +30,7 @@ import { addRequestMeta } from '../server/request-meta'
import { normalizeAppPath } from '../shared/lib/router/utils/app-paths'
import { REDIRECT_ERROR_CODE } from '../client/components/redirect'
import { DYNAMIC_ERROR_CODE } from '../client/components/hooks-server-context'
import { NOT_FOUND_ERROR_CODE } from '../client/components/not-found'

loadRequireHook()
const envConfig = require('../shared/lib/runtime-config')
Expand Down Expand Up @@ -419,7 +420,8 @@ export default async function exportPage({
} catch (err: any) {
if (
err.digest !== DYNAMIC_ERROR_CODE &&
err.digest !== REDIRECT_ERROR_CODE
err.digest !== NOT_FOUND_ERROR_CODE &&
!err.digest?.startsWith(REDIRECT_ERROR_CODE)
) {
throw err
}
Expand Down
24 changes: 4 additions & 20 deletions packages/next/server/app-render.tsx
Expand Up @@ -31,6 +31,7 @@ import type { ComponentsType } from '../build/webpack/loaders/next-app-loader'
import { REDIRECT_ERROR_CODE } from '../client/components/redirect'
import { NextCookies } from './web/spec-extension/cookies'
import { DYNAMIC_ERROR_CODE } from '../client/components/hooks-server-context'
import { NOT_FOUND_ERROR_CODE } from '../client/components/not-found'

const INTERNAL_HEADERS_INSTANCE = Symbol('internal for headers readonly')

Expand Down Expand Up @@ -173,7 +174,8 @@ function createErrorHandler(
if (
// TODO-APP: Handle redirect throw
err.digest !== DYNAMIC_ERROR_CODE &&
err.digest !== REDIRECT_ERROR_CODE
err.digest !== NOT_FOUND_ERROR_CODE &&
!err.digest?.startsWith(REDIRECT_ERROR_CODE)
) {
// Used for debugging error source
// console.error(_source, err)
Expand Down Expand Up @@ -1299,10 +1301,6 @@ export async function renderToHTMLOrFlight(
flushEffectsToHead: true,
})
} catch (err: any) {
if (err.digest === REDIRECT_ERROR_CODE) {
throw err
}

// TODO-APP: show error overlay in development. `element` should probably be wrapped in AppRouter for this case.
const renderStream = await renderToInitialStream({
ReactDOMServer,
Expand Down Expand Up @@ -1358,21 +1356,7 @@ export async function renderToHTMLOrFlight(
return new RenderResult(staticHtml)
}

try {
return new RenderResult(await bodyResult())
} catch (err: any) {
if (err.digest === REDIRECT_ERROR_CODE) {
;(renderOpts as any).pageData = {
pageProps: {
__N_REDIRECT: err.url,
__N_REDIRECT_STATUS: 307,
},
}
;(renderOpts as any).isRedirect = true
return RenderResult.fromStatic('')
}
throw err
}
return new RenderResult(await bodyResult())
}

const initialStaticGenerationStore = {
Expand Down
3 changes: 1 addition & 2 deletions test/e2e/app-dir/index.test.ts
Expand Up @@ -1490,8 +1490,7 @@ describe('app dir', () => {
await browser.waitForElementByCss('#not-found-component').text()
).toBe('404!')
})

it('should trigger 404 client-side', async () => {
;(isDev ? it.skip : it)('should trigger 404 client-side', async () => {
const browser = await webdriver(next.url, '/not-found/client-side')
await browser
.elementByCss('button')
Expand Down

0 comments on commit 8b802dd

Please sign in to comment.