Skip to content

Commit

Permalink
fix: Error: NEXT_REDIRECT crashing server in prod (#42793)
Browse files Browse the repository at this point in the history
Fixes: #42587

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have a helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm build && pnpm lint`
- [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
  • Loading branch information
Hannes Bornö committed Nov 15, 2022
1 parent 0f8b3d6 commit a0e5178
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/next/server/app-render.tsx
Expand Up @@ -59,6 +59,24 @@ function preloadComponent(Component: any, props: any) {
}
try {
let result = Component(props)
if (result && result.then) {
result = result
.then((res: any) => {
return { success: res }
})
.catch((err: Error) => {
return { error: err }
})
return async () => {
const res = await result
if (res.error) {
throw res.error
}
if (res.success) {
return res.success
}
}
}
return function () {
// We know what this component will render already.
return result
Expand Down
29 changes: 29 additions & 0 deletions test/e2e/app-dir/async-component-preload.test.ts
@@ -0,0 +1,29 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import webdriver from 'next-webdriver'
import path from 'path'

describe('async-component-preload', () => {
if ((global as any).isNextDeploy) {
it('should skip next deploy for now', () => {})
return
}

let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: new FileRef(path.join(__dirname, 'async-component-preload')),
dependencies: {
react: 'latest',
'react-dom': 'latest',
},
})
})
afterAll(() => next.destroy())

it('should handle redirect in an async page', async () => {
const browser = await webdriver(next.url, '/')
expect(await browser.waitForElementByCss('#success').text()).toBe('Success')
})
})
12 changes: 12 additions & 0 deletions test/e2e/app-dir/async-component-preload/app/layout.js
@@ -0,0 +1,12 @@
export const revalidate = 0

export default async function RootLayout({ children }) {
await new Promise((resolve) => setTimeout(resolve, 0))

return (
<html lang="en">
<head />
<body>{children}</body>
</html>
)
}
6 changes: 6 additions & 0 deletions test/e2e/app-dir/async-component-preload/app/page.js
@@ -0,0 +1,6 @@
import { redirect } from 'next/navigation'

export default async function Home() {
redirect('success')
return <h1>Home</h1>
}
3 changes: 3 additions & 0 deletions test/e2e/app-dir/async-component-preload/app/success/page.js
@@ -0,0 +1,3 @@
export default function Success() {
return <p id="success">Success</p>
}
5 changes: 5 additions & 0 deletions test/e2e/app-dir/async-component-preload/next.config.js
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
appDir: true,
},
}

0 comments on commit a0e5178

Please sign in to comment.