codeburn/app/renderer/components/ErrorBoundary.tsx
iamtoruk 781d37674b feat(app): error boundary so a crashing screen shows the error, not a blank
A render error in any section previously white-screened the whole app
(no boundary). Wrap the section content in an ErrorBoundary keyed by
section: the error message + component stack render in a card, the
sidebar stays usable, and navigating away recovers. Logs to the console
for diagnosis.
2026-07-11 14:33:16 -07:00

40 lines
1.4 KiB
TypeScript

import { Component, type ErrorInfo, type ReactNode } from 'react'
type Props = { children: ReactNode }
type State = { error: Error | null; stack: string | null }
/**
* Catches render/lifecycle errors in a screen so a single crashing section
* shows a readable error instead of white-screening the whole app. Keyed by
* section in App, so navigating to another screen remounts and recovers.
*/
export class ErrorBoundary extends Component<Props, State> {
state: State = { error: null, stack: null }
static getDerivedStateFromError(error: Error): Partial<State> {
return { error }
}
componentDidCatch(error: Error, info: ErrorInfo): void {
// Surface to the renderer console for diagnosis in dev.
console.error('Screen crashed:', error, info.componentStack)
this.setState({ stack: info.componentStack ?? null })
}
render(): ReactNode {
const { error, stack } = this.state
if (!error) return this.props.children
return (
<div className="error-boundary">
<div className="panel error-card">
<h3 className="error-title">This screen hit an error</h3>
<p className="error-msg">{error.message || String(error)}</p>
{stack && <pre className="error-stack">{stack.trim()}</pre>}
<button className="btn" type="button" onClick={() => window.location.reload()}>
Reload
</button>
</div>
</div>
)
}
}