Files
certctl/web/src/components/ErrorBoundary.tsx
T
shankar0123 bb7a78352e fix: frontend error handling — ErrorBoundary, type-safe errors, stable keys
- React ErrorBoundary wrapping entire app for graceful crash recovery
- fetchJSON error handling uses try/catch instead of .catch() chain
- CertificateDetailPage: instanceof checks replace unsafe type casts
- DataTable: keyField prop replaces array index keys

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 01:20:32 -04:00

51 lines
1.4 KiB
TypeScript

import { Component, type ErrorInfo, type ReactNode } from 'react';
interface Props {
children: ReactNode;
}
interface State {
hasError: boolean;
error: Error | null;
}
export default class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Uncaught component error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div className="flex items-center justify-center min-h-screen bg-slate-900">
<div className="text-center p-8">
<h1 className="text-xl font-semibold text-red-400 mb-2">Something went wrong</h1>
<p className="text-sm text-slate-400 mb-4">
{this.state.error?.message || 'An unexpected error occurred'}
</p>
<button
onClick={() => {
this.setState({ hasError: false, error: null });
window.location.reload();
}}
className="px-4 py-2 bg-blue-600 text-white rounded-lg text-sm hover:bg-blue-500"
>
Reload Page
</button>
</div>
</div>
);
}
return this.props.children;
}
}