/** * Error Boundary Component * * Catches JavaScript errors in child component tree and displays fallback UI. * Prevents the entire app from crashing due to component-level errors. * * @see https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary */ 'use client'; import { Component, type ReactNode } from 'react'; import { AlertTriangle, RefreshCw } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; // ============================================================================ // Types // ============================================================================ interface ErrorBoundaryProps { /** Child components to render */ children: ReactNode; /** Optional fallback component to render on error */ fallback?: ReactNode; /** Optional callback when error occurs */ onError?: (error: Error, errorInfo: React.ErrorInfo) => void; /** Whether to show reset button (default: true) */ showReset?: boolean; } interface ErrorBoundaryState { hasError: boolean; error: Error | null; } // ============================================================================ // Default Fallback Component // ============================================================================ interface DefaultFallbackProps { error: Error | null; onReset: () => void; showReset: boolean; } function DefaultFallback({ error, onReset, showReset }: DefaultFallbackProps) { return ( An unexpected error occurred. Please try again or contact support if the problem persists. {error && (

{error.message}

)} {showReset && ( )}
); } // ============================================================================ // Error Boundary Component // ============================================================================ /** * Error boundary for catching and handling render errors in React components. * * @example * ```tsx * logError(error)}> * * * ``` * * @example With custom fallback * ```tsx * }> * * * ``` */ export class ErrorBoundary extends Component { constructor(props: ErrorBoundaryProps) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error: Error): ErrorBoundaryState { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void { // Log error to console in development console.error('ErrorBoundary caught an error:', error, errorInfo); // Call optional error callback this.props.onError?.(error, errorInfo); } handleReset = (): void => { this.setState({ hasError: false, error: null }); }; render(): ReactNode { const { hasError, error } = this.state; const { children, fallback, showReset = true } = this.props; if (hasError) { if (fallback) { return fallback; } return ; } return children; } } export default ErrorBoundary;