3f1a61b18f
- Remove unused code - Keep rendering underlying component tree when there is a build error - Move error catch up one level ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
80 lines
2 KiB
TypeScript
80 lines
2 KiB
TypeScript
import * as React from 'react'
|
|
import {
|
|
ACTION_UNHANDLED_ERROR,
|
|
OverlayState,
|
|
UnhandledErrorAction,
|
|
} from './error-overlay-reducer'
|
|
|
|
import { ShadowPortal } from './components/ShadowPortal'
|
|
import { BuildError } from './container/BuildError'
|
|
import { Errors, SupportedErrorEvent } from './container/Errors'
|
|
import { Base } from './styles/Base'
|
|
import { ComponentStyles } from './styles/ComponentStyles'
|
|
import { CssReset } from './styles/CssReset'
|
|
import { parseStack } from './helpers/parseStack'
|
|
|
|
interface ReactDevOverlayState {
|
|
reactError: SupportedErrorEvent | null
|
|
}
|
|
class ReactDevOverlay extends React.PureComponent<
|
|
{
|
|
state: OverlayState
|
|
children: React.ReactNode
|
|
},
|
|
ReactDevOverlayState
|
|
> {
|
|
state = { reactError: null }
|
|
|
|
static getDerivedStateFromError(error: Error): ReactDevOverlayState {
|
|
const e = error
|
|
const event: UnhandledErrorAction = {
|
|
type: ACTION_UNHANDLED_ERROR,
|
|
reason: error,
|
|
frames: parseStack(e.stack!),
|
|
}
|
|
const errorEvent: SupportedErrorEvent = {
|
|
id: 0,
|
|
event,
|
|
}
|
|
return { reactError: errorEvent }
|
|
}
|
|
|
|
render() {
|
|
const { state, children } = this.props
|
|
const { reactError } = this.state
|
|
|
|
const hasBuildError = state.buildError != null
|
|
const hasRuntimeErrors = Boolean(state.errors.length)
|
|
const isMounted = hasBuildError || hasRuntimeErrors || reactError
|
|
|
|
return (
|
|
<>
|
|
{reactError ? (
|
|
<html>
|
|
<head></head>
|
|
<body></body>
|
|
</html>
|
|
) : (
|
|
children
|
|
)}
|
|
{isMounted ? (
|
|
<ShadowPortal>
|
|
<CssReset />
|
|
<Base />
|
|
<ComponentStyles />
|
|
|
|
{hasBuildError ? (
|
|
<BuildError message={state.buildError!} />
|
|
) : hasRuntimeErrors ? (
|
|
<Errors errors={state.errors} />
|
|
) : reactError ? (
|
|
<Errors errors={[reactError]} />
|
|
) : undefined}
|
|
</ShadowPortal>
|
|
) : undefined}
|
|
</>
|
|
)
|
|
}
|
|
}
|
|
|
|
export default ReactDevOverlay
|