Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Correct statusCode when visiting _error directly (vercel#26610)
Browse files Browse the repository at this point in the history
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: vercel#8036
x-ref: vercel#8033
  • Loading branch information
ijjk authored Jun 28, 2021
1 parent 93dc35f commit 39dd0f5
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 37 deletions.
5 changes: 5 additions & 0 deletions packages/next/next-server/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' &&
Expand All @@ -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)) {
Expand Down
54 changes: 17 additions & 37 deletions test/integration/client-navigation/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit 39dd0f5

Please sign in to comment.