Add ErrorBoundary class component with retry support

This commit is contained in:
2026-04-15 00:30:34 +03:00
parent 1409df458b
commit 2eb118cb8b
+56
View File
@@ -0,0 +1,56 @@
import { Component } from "react";
import type { ReactNode, ErrorInfo } from "react";
export interface ErrorBoundaryProps {
children: ReactNode;
fallback?: ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
error: Error | null;
}
/**
* React error boundary that catches render-time exceptions in the subtree.
* Displays a minimal fallback UI with a "Retry" button that resets state.
*
* Must be a class component — React requires componentDidCatch / getDerivedStateFromError.
*/
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
override state: ErrorBoundaryState = { hasError: false, error: null };
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error };
}
override componentDidCatch(error: Error, info: ErrorInfo): void {
// Phase 1G-logger will replace this with useLogger() context logging.
// For now, write to console so errors are not silently swallowed.
console.error("[ErrorBoundary]", error, info.componentStack);
}
private readonly handleRetry = (): void => {
this.setState({ hasError: false, error: null });
};
override render(): ReactNode {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return (
<div role="alert">
<h2>Something went wrong</h2>
<p>{this.state.error?.message}</p>
<button type="button" onClick={this.handleRetry}>
Retry
</button>
</div>
);
}
return this.props.children;
}
}