forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
error-boundary.tsx
123 lines (110 loc) · 2.71 KB
/
error-boundary.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
'use client'
import React from 'react'
const styles = {
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',
},
text: {
fontSize: '14px',
fontWeight: 'normal',
lineHeight: '49px',
margin: 0,
padding: 0,
},
} as const
export type ErrorComponent = React.ComponentType<{
error: Error
reset: () => void
}>
export interface ErrorBoundaryProps {
errorComponent: ErrorComponent
errorStyles?: React.ReactNode | undefined
}
export class ErrorBoundaryHandler extends React.Component<
ErrorBoundaryProps,
{ error: Error | null }
> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = { error: null }
}
static getDerivedStateFromError(error: Error) {
return { error }
}
reset = () => {
this.setState({ error: null })
}
render() {
if (this.state.error) {
return (
<>
{this.props.errorStyles}
<this.props.errorComponent
error={this.state.error}
reset={this.reset}
/>
</>
)
}
return this.props.children
}
}
export default function GlobalError({ error }: { error: any }) {
return (
<html>
<head></head>
<body>
<div style={styles.error}>
<div style={styles.desc}>
<h2 style={styles.text}>
Application error: a client-side exception has occurred (see the
browser console for more information).
</h2>
{error?.digest && (
<p style={styles.text}>{`Digest: ${error.digest}`}</p>
)}
</div>
</div>
</body>
</html>
)
}
/**
* Handles errors through `getDerivedStateFromError`.
* Renders the provided error component and provides a way to `reset` the error boundary state.
*/
/**
* Renders error boundary with the provided "errorComponent" property as the fallback.
* If no "errorComponent" property is provided it renders the children without an error boundary.
*/
export function ErrorBoundary({
errorComponent,
errorStyles,
children,
}: ErrorBoundaryProps & { children: React.ReactNode }): JSX.Element {
if (errorComponent) {
return (
<ErrorBoundaryHandler
errorComponent={errorComponent}
errorStyles={errorStyles}
>
{children}
</ErrorBoundaryHandler>
)
}
return <>{children}</>
}