1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Set default Error status code to 404 (#6276)

* Set default `Error` status code to 404

This is an appropriate default behavior because:

1. When the server encounters an error, the `err` property is set.
2. When the client-side application crashes, the `err` property is set.

This means the "only" way to render the `/_error` page without an error
is when a page is not found (special condition).

Fixes #6243
Closes #5437

* Add new integration test for client side 404

* single quotes

* Remove unused variable

* Standard needs to go away

* Whoops

* Check for null status code in res and err

* Only check response for valid statusCode
This commit is contained in:
Joe Haddad 2019-02-12 21:32:25 -05:00 committed by GitHub
parent 68db0992b6
commit f43e1a95f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 16 deletions

View file

@ -7,29 +7,38 @@ export default class Error extends React.Component {
static displayName = 'ErrorPage'
static getInitialProps ({ res, err }) {
const statusCode = res ? res.statusCode : (err ? err.statusCode : null)
const statusCode =
res && res.statusCode ? res.statusCode : err ? err.statusCode : 404
return { statusCode }
}
render () {
const { statusCode } = this.props
const title = statusCode === 404
? 'This page could not be found'
: HTTPStatus[statusCode] || 'An unexpected error has occurred'
const title =
statusCode === 404
? 'This page could not be found'
: HTTPStatus[statusCode] || 'An unexpected error has occurred'
return <div style={styles.error}>
<Head>
<meta name='viewport' content='width=device-width, initial-scale=1.0' />
<title>{statusCode}: {title}</title>
</Head>
<div>
<style dangerouslySetInnerHTML={{ __html: 'body { margin: 0 }' }} />
{statusCode ? <h1 style={styles.h1}>{statusCode}</h1> : null}
<div style={styles.desc}>
<h2 style={styles.h2}>{title}.</h2>
return (
<div style={styles.error}>
<Head>
<meta
name='viewport'
content='width=device-width, initial-scale=1.0'
/>
<title>
{statusCode}: {title}
</title>
</Head>
<div>
<style dangerouslySetInnerHTML={{ __html: 'body { margin: 0 }' }} />
{statusCode ? <h1 style={styles.h1}>{statusCode}</h1> : null}
<div style={styles.desc}>
<h2 style={styles.h2}>{title}.</h2>
</div>
</div>
</div>
</div>
)
}
}
@ -43,7 +52,8 @@ const styles = {
error: {
color: '#000',
background: '#fff',
fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
fontFamily:
'-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
height: '100vh',
textAlign: 'center',
display: 'flex',

View file

@ -0,0 +1,6 @@
module.exports = {
onDemandEntries: {
// Make sure entries are not getting disposed.
maxInactiveAge: 1000 * 60 * 60
}
}

View file

@ -0,0 +1,23 @@
import Link from 'next/link'
import NextError from 'next/error'
import React from 'react'
export default class Error extends React.Component {
static getInitialProps (ctx) {
const { statusCode } = NextError.getInitialProps(ctx)
return { statusCode: statusCode || null }
}
render () {
return (
<div>
<div id='errorStatusCode'>{this.props.statusCode || 'unknown'}</div>
<p>
<Link href='/'>
<a id='errorGoHome'>go home</a>
</Link>
</p>
</div>
)
}
}

View file

@ -0,0 +1 @@
export default () => <div id='hellom8'>OK</div>

View file

@ -0,0 +1,27 @@
/* eslint-env jest */
import webdriver from 'next-webdriver'
export default (context) => {
describe('Client Navigation 404', () => {
describe('should show 404 upon client replacestate', () => {
it('should navigate the page', async () => {
const browser = await webdriver(context.appPort, '/asd')
const serverCode = await browser
.waitForElementByCss('#errorStatusCode')
.text()
await browser.waitForElementByCss('#errorGoHome').click()
await browser.waitForElementByCss('#hellom8').back()
const clientCode = await browser
.waitForElementByCss('#errorStatusCode')
.text()
expect({ serverCode, clientCode }).toMatchObject({
serverCode: '404',
clientCode: '404'
})
browser.close()
})
})
})
}

View file

@ -0,0 +1,23 @@
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import { renderViaHTTP, findPort, launchApp, killApp } from 'next-test-utils'
// test suite
import clientNavigation from './client-navigation'
const context = {}
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5
describe('Client 404', () => {
beforeAll(async () => {
context.appPort = await findPort()
context.server = await launchApp(join(__dirname, '../'), context.appPort)
// pre-build page at the start
await renderViaHTTP(context.appPort, '/')
})
afterAll(() => killApp(context.server))
clientNavigation(context, (p, q) => renderViaHTTP(context.appPort, p, q))
})