rsnext/packages/next/client/components/react-dev-overlay/internal/ReactDevOverlay.tsx
Tim Neutkens 3f1a61b18f
Ensure content is kept rendered below the error overlay on build errors in new router (#41360)
- 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)
2022-10-12 14:36:24 +00:00

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