forked from vercel/next.js
/
_error.tsx
136 lines (123 loc) · 3.33 KB
/
_error.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import React from 'react'
import Head from '../shared/lib/head'
import type { NextPageContext } from '../shared/lib/utils'
const statusCodes: { [code: number]: string } = {
400: 'Bad Request',
404: 'This page could not be found',
405: 'Method Not Allowed',
500: 'Internal Server Error',
}
export type ErrorProps = {
statusCode: number
title?: string
withDarkMode?: boolean
}
function _getInitialProps({
res,
err,
}: NextPageContext): Promise<ErrorProps> | ErrorProps {
const statusCode =
res && res.statusCode ? res.statusCode : err ? err.statusCode! : 404
return { statusCode }
}
/**
* `Error` component used for handling errors.
*/
export default class Error<P = {}> extends React.Component<P & ErrorProps> {
static displayName = 'ErrorPage'
static getInitialProps = _getInitialProps
static origGetInitialProps = _getInitialProps
render() {
const { statusCode, withDarkMode = true } = this.props
const title =
this.props.title ||
statusCodes[statusCode] ||
'An unexpected error has occurred'
return (
<div style={styles.error}>
<Head>
<title>
{statusCode
? `${statusCode}: ${title}`
: 'Application error: a client-side exception has occurred'}
</title>
</Head>
<div>
<style
dangerouslySetInnerHTML={{
__html: `
body { margin: 0; color: #000; background: #fff; }
.next-error-h1 {
border-right: 1px solid rgba(0, 0, 0, .3);
}
${
withDarkMode
? `@media (prefers-color-scheme: dark) {
body { color: #fff; background: #000; }
.next-error-h1 {
border-right: 1px solid rgba(255, 255, 255, .3);
}
}`
: ''
}`,
}}
/>
{statusCode ? (
<h1 className="next-error-h1" style={styles.h1}>
{statusCode}
</h1>
) : null}
<div style={styles.desc}>
<h2 style={styles.h2}>
{this.props.title || statusCode ? (
title
) : (
<>
Application error: a client-side exception has occurred (see
the browser console for more information)
</>
)}
.
</h2>
</div>
</div>
</div>
)
}
}
const styles: { [k: string]: React.CSSProperties } = {
error: {
fontFamily:
'-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
height: '100vh',
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
},
desc: {
display: 'inline-block',
textAlign: 'left',
lineHeight: '49px',
height: '49px',
verticalAlign: 'middle',
},
h1: {
display: 'inline-block',
margin: 0,
marginRight: '20px',
padding: '0 23px 0 0',
fontSize: '24px',
fontWeight: 500,
verticalAlign: 'top',
lineHeight: '49px',
},
h2: {
fontSize: '14px',
fontWeight: 'normal',
lineHeight: '49px',
margin: 0,
padding: 0,
},
}