StaticgetUpdates state when an error is caught to trigger fallback UI.
The thrown error.
Partial state to set hasError flag.
Logs error details and stores error info when an error is caught.
The thrown error.
React error info with component stack.
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
// Log error to console
console.error("🚨 [ErrorBoundary] Caught error:", error);
console.error("🚨 [ErrorBoundary] Error info:", errorInfo);
// Update state with error info
this.setState({
error,
errorInfo,
});
// Capture to Sentry with React context
Sentry.captureException(error, {
contexts: {
react: {
componentStack: errorInfo.componentStack,
},
},
fingerprint: ["{{ default }}", error.message],
});
// Call onError callback if provided
if (this.props.onError) {
this.props.onError(error, errorInfo);
}
// Dispatch error to debug context if available
try {
const debugEvent = new CustomEvent("debug:log", {
detail: {
type: "app.error",
message: `React Error: ${error.message}`,
level: "error",
metadata: {
stack: error.stack,
componentStack: errorInfo.componentStack,
},
},
});
globalThis.dispatchEvent(debugEvent);
} catch (e) {
console.error("Failed to log error to debug context:", e);
}
}
Renders the error boundary UI or children. Displays custom fallback if provided, otherwise shows default error UI with recovery options.
Error UI or children based on error state.
render(): ReactNode {
if (this.state.hasError) {
// Use custom fallback if provided
if (this.props.fallback) {
return this.props.fallback;
}
// Default error UI
return (
<div className="bg-background flex min-h-screen items-center justify-center p-4">
<Card className="border-destructive w-full max-w-2xl">
<CardHeader>
<div className="flex items-center gap-3">
<div className="bg-destructive/10 rounded-full p-2">
<AlertTriangle className="text-destructive h-6 w-6" />
</div>
<div>
<CardTitle className="text-2xl">
Something went wrong
</CardTitle>
<CardDescription>
The application encountered an unexpected error
</CardDescription>
</div>
</div>
</CardHeader>
<CardContent className="space-y-4">
<div className="bg-muted rounded-lg p-4">
<h4 className="mb-2 text-sm font-semibold">Error Details:</h4>
<p className="text-destructive font-mono text-sm">
{this.state.error?.message || "Unknown error"}
</p>
</div>
{this.state.error?.stack && (
<details className="cursor-pointer">
<summary className="text-sm font-semibold hover:underline">
Stack Trace
</summary>
<pre className="bg-muted mt-2 max-h-64 overflow-auto rounded-lg p-4 font-mono text-xs">
{this.state.error.stack}
</pre>
</details>
)}
{this.state.errorInfo?.componentStack && (
<details className="cursor-pointer">
<summary className="text-sm font-semibold hover:underline">
Component Stack
</summary>
<pre className="bg-muted mt-2 max-h-64 overflow-auto rounded-lg p-4 font-mono text-xs">
{this.state.errorInfo.componentStack}
</pre>
</details>
)}
<div className="border-border bg-card rounded-lg border p-4">
<p className="text-muted-foreground text-sm">
<strong>What you can do:</strong>
</p>
<ul className="text-muted-foreground mt-2 list-inside list-disc space-y-1 text-sm">
<li>Try reloading the page</li>
<li>Check the developer console for more details</li>
<li>Report this issue if it persists</li>
</ul>
</div>
</CardContent>
<CardFooter className="flex flex-wrap gap-2">
<Button onClick={this.handleReset} variant="default" size="sm">
<RotateCcw className="mr-2 h-4 w-4" />
Try Again
</Button>
<Button onClick={this.handleReload} variant="outline" size="sm">
<RotateCcw className="mr-2 h-4 w-4" />
Reload App
</Button>
<Button onClick={this.handleGoHome} variant="ghost" size="sm">
<Home className="mr-2 h-4 w-4" />
Go Home
</Button>
</CardFooter>
</Card>
</div>
);
}
return this.props.children;
}
Error boundary component that catches React errors and displays error UI. Logs errors for debugging and attempts to dispatch to debug context.
Source