import { Component, type ErrorInfo, type ReactNode } from 'react' // The last line of defence for a render throw. // // React unmounts the whole tree when a render throws and nothing catches it, so a single bad // dereference anywhere produced a permanently blank page: no message, no navigation, no way back except // reloading, and nothing on screen saying a reload would help. That is not a hypothetical here. Go // marshals a nil slice as JSON `null`, none of the Command Center DTO fields carry omitempty, and several // screens map straight over those arrays, so an organization with no opportunities is enough to throw. // // This is deliberately a class component: error boundaries have no hook equivalent, getDerivedStateFromError // and componentDidCatch are the only React API for catching a descendant's render error. type Props = { children: ReactNode } type State = { error: Error | null } export class ErrorBoundary extends Component { state: State = { error: null } static getDerivedStateFromError(error: Error): State { return { error } } componentDidCatch(error: Error, info: ErrorInfo) { // Logged rather than swallowed, so the stack survives in the console for whoever is diagnosing it. // There is no error reporting transport yet; when one exists this is the single place to attach it. console.error('missionMATCH: unhandled render error', error, info.componentStack) } private reset = () => this.setState({ error: null }) render() { if (!this.state.error) return this.props.children return (

Something broke on this screen.

The rest of the application is still running. Your work was not lost: nothing is saved from this screen until you submit it.

            {this.state.error.message}
          
{/* Try again re mounts the subtree, which recovers from a transient failure without losing the session. Go home is the escape hatch when the screen itself is the problem. */}
) } }