import { Component, type ErrorInfo, type ReactNode } from "react"; import { AlertTriangle, RefreshCw } from "lucide-react"; import { Button } from "@/components/ui"; /** * Catches render errors so one broken page does not blank the whole app. * * Without this, any exception thrown while rendering unmounts the entire React * tree: the user gets a white window with no navigation and no indication of * what happened, and the only way out is to know to reload. React offers no * hook equivalent — catching render errors requires a class component. * * `resetKey` is how the boundary recovers on navigation: change it (the route * path) and the boundary clears, so moving to a working page just works instead * of staying stuck on the error screen. */ interface Props { children: ReactNode; /** Changing this clears a caught error — pass the current route. */ resetKey?: string; } interface State { error: Error | null; } export class ErrorBoundary extends Component { state: State = { error: null }; static getDerivedStateFromError(error: Error): State { return { error }; } componentDidUpdate(prev: Props) { if (this.state.error && prev.resetKey !== this.props.resetKey) { this.setState({ error: null }); } } componentDidCatch(error: Error, info: ErrorInfo) { // The browser console is the only place this can go — there is no error // reporting backend, and inventing one is not this component's job. console.error("Render error:", error, info.componentStack); } render() { const { error } = this.state; if (!error) return this.props.children; return (

This page hit an error

The rest of StackPilot is still running — your stacks are unaffected. Try again, or pick another page from the menu.

          {error.message || String(error)}
        
); } }