All files / src/components/ErrorBoundary ErrorBoundary.tsx

93.75% Statements 15/16
80% Branches 4/5
100% Functions 2/2
90% Lines 9/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                                                                12x 12x   5x   5x   5x       5x             5x   12x   12x              
import { type ErrorInfo, type ReactNode } from 'react';
import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary';
import { ErrorFallback } from './ErrorFallback';
 
interface ErrorBoundaryProps {
  children: ReactNode;
  /**
   * Optional custom fallback component
   */
  fallback?: ReactNode;
  /**
   * Optional callback when error occurs
   */
  onError?: (error: Error, info: ErrorInfo) => void;
  /**
   * Context identifier for error logging (e.g., 'Router', 'QueryProvider', 'Dashboard')
   */
  context?: string;
}
 
/**
 * ErrorBoundary wrapper for the react-error-boundary library.
 *
 * Catches JavaScript errors anywhere in the child component tree,
 * logs those errors, and displays a fallback UI.
 *
 * @example
 * ```tsx
 * <ErrorBoundary context="Dashboard">
 *   <DashboardPage />
 * </ErrorBoundary>
 * ```
 *
 * @see docs/interfaces/react-coding-standards.md for standards and best practices
 */
export function ErrorBoundary({
  children,
  fallback,
  onError,
  context = 'Application',
}: ErrorBoundaryProps) {
  const handleError = (error: Error, info: ErrorInfo) => {
    // Log to console in development
    if (import.meta.env.DEV) {
      // eslint-disable-next-line no-console
      console.error(`[ErrorBoundary:${context}] Error caught:`, error);
      // eslint-disable-next-line no-console
      console.error('Component stack:', info.componentStack);
    E}
 
    // Call custom error handler if provided
    onError?.(error, info);
 
    // TODO: Send to error tracking service (e.g., Sentry, LogRocket)
    // errorTrackingService.captureException(error, {
    //   context,
    //   componentStack: info.componentStack,
    // });
  };
 
  return (
    <ReactErrorBoundary
      fallback={fallback ?? <ErrorFallback context={context} />}
      onError={handleError}
    >
      {children}
    </ReactErrorBoundary>
  );
}