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:
parent
68db0992b6
commit
f43e1a95f1
|
@ -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',
|
||||
|
|
6
test/integration/client-404/next.config.js
Normal file
6
test/integration/client-404/next.config.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
module.exports = {
|
||||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
}
|
||||
}
|
23
test/integration/client-404/pages/_error.js
Normal file
23
test/integration/client-404/pages/_error.js
Normal 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>
|
||||
)
|
||||
}
|
||||
}
|
1
test/integration/client-404/pages/index.js
Normal file
1
test/integration/client-404/pages/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export default () => <div id='hellom8'>OK</div>
|
27
test/integration/client-404/test/client-navigation.js
Normal file
27
test/integration/client-404/test/client-navigation.js
Normal 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()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
23
test/integration/client-404/test/index.test.js
Normal file
23
test/integration/client-404/test/index.test.js
Normal 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))
|
||||
})
|
Loading…
Reference in a new issue