Correct statusCode when visiting _error directly (#26610)
This fixes non-stop reloading when visiting `_error` directly in development caused by the `statusCode` being 200 unexpectedly while HMR returns the page as `invalid` which triggers `on-demand-entries` to reload the page. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added Fixes: https://github.com/vercel/next.js/issues/8036 x-ref: https://github.com/vercel/next.js/pull/8033
This commit is contained in:
parent
ae0dbe5e2c
commit
c2f0653bd3
2 changed files with 22 additions and 37 deletions
|
@ -1444,6 +1444,7 @@ export default class Server {
|
|||
): Promise<string | null> {
|
||||
const is404Page = pathname === '/404'
|
||||
const is500Page = pathname === '/500'
|
||||
const isErrorPage = pathname === '/_error'
|
||||
|
||||
const isLikeServerless =
|
||||
typeof components.Component === 'object' &&
|
||||
|
@ -1462,6 +1463,10 @@ export default class Server {
|
|||
res.statusCode = 404
|
||||
}
|
||||
|
||||
if (isErrorPage && res.statusCode === 200) {
|
||||
res.statusCode = 404
|
||||
}
|
||||
|
||||
// ensure correct status is set when visiting a status page
|
||||
// directly e.g. /500
|
||||
if (STATIC_STATUS_PAGES.includes(pathname)) {
|
||||
|
|
|
@ -25,46 +25,26 @@ describe('Client Navigation', () => {
|
|||
context.server = await launchApp(join(__dirname, '../'), context.appPort, {
|
||||
env: { __NEXT_TEST_WITH_DEVTOOL: 1 },
|
||||
})
|
||||
|
||||
const prerender = [
|
||||
'/async-props',
|
||||
'/default-head',
|
||||
'/empty-get-initial-props',
|
||||
'/error',
|
||||
'/finish-response',
|
||||
'/head',
|
||||
'/json',
|
||||
'/link',
|
||||
'/stateless',
|
||||
'/fragment-syntax',
|
||||
'/custom-extension',
|
||||
'/styled-jsx',
|
||||
'/styled-jsx-external',
|
||||
'/with-cdm',
|
||||
'/url-prop',
|
||||
|
||||
'/dynamic/ssr',
|
||||
'/dynamic/[slug]/route',
|
||||
|
||||
'/nav',
|
||||
'/nav/about',
|
||||
'/nav/on-click',
|
||||
'/nav/querystring',
|
||||
'/nav/self-reload',
|
||||
'/nav/hash-changes',
|
||||
'/nav/shallow-routing',
|
||||
'/nav/redirect',
|
||||
'/nav/as-path',
|
||||
'/nav/as-path-using-router',
|
||||
|
||||
'/nested-cdm',
|
||||
]
|
||||
await Promise.all(
|
||||
prerender.map((route) => renderViaHTTP(context.appPort, route))
|
||||
)
|
||||
})
|
||||
afterAll(() => killApp(context.server))
|
||||
|
||||
it('should not reload when visiting /_error directly', async () => {
|
||||
const browser = await webdriver(context.appPort, '/_error')
|
||||
|
||||
await browser.eval('window.hello = true')
|
||||
|
||||
// wait on-demand-entries timeout since it can trigger
|
||||
// reloading non-stop
|
||||
for (let i = 0; i < 15; i++) {
|
||||
expect(await browser.eval('window.hello')).toBe(true)
|
||||
await waitFor(1000)
|
||||
}
|
||||
const html = await browser.eval('document.documentElement.innerHTML')
|
||||
|
||||
expect(html).toContain('This page could not be found')
|
||||
expect(html).toContain('404')
|
||||
})
|
||||
|
||||
describe('with <Link/>', () => {
|
||||
it('should navigate the page', async () => {
|
||||
const browser = await webdriver(context.appPort, '/nav')
|
||||
|
|
Loading…
Reference in a new issue