All files / web/src/components error-boundary.tsx

100% Statements 42/42
100% Branches 11/11
100% Functions 5/5
100% Lines 42/42

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    1x                         1x     1x 1x 19x 19x 19x   1x 12x 12x   1x 6x 6x 6x   1x 31x 12x 4x 4x   8x 8x 8x   8x 8x   8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x   8x 8x   8x   19x 31x 1x  
'use client';
 
import { Component, type ErrorInfo, type ReactNode } from 'react';
 
interface ErrorBoundaryState {
  hasError: boolean;
  error?: Error;
}
 
interface ErrorBoundaryProps {
  children: ReactNode;
  fallback?: (error: Error) => ReactNode;
  onError?: (error: Error, errorInfo: ErrorInfo) => void;
}
 
export class ErrorBoundary extends Component<
  ErrorBoundaryProps,
  ErrorBoundaryState
> {
  constructor(props: ErrorBoundaryProps) {
    super(props);
    this.state = { hasError: false };
  }
 
  static getDerivedStateFromError(error: Error): ErrorBoundaryState {
    return { hasError: true, error };
  }
 
  componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
    console.error('ErrorBoundary caught an error:', error, errorInfo);
    this.props.onError?.(error, errorInfo);
  }
 
  render(): ReactNode {
    if (this.state.hasError && this.state.error) {
      if (this.props.fallback) {
        return this.props.fallback(this.state.error);
      }
 
      return (
        <div className="flex flex-col items-center justify-center p-8 text-center">
          <h2 className="text-lg font-semibold text-red-600 mb-2">
            Something went wrong
          </h2>
          <p className="text-sm text-gray-600 mb-4">
            An error occurred while loading this component.
          </p>
          <details className="text-xs text-gray-500 max-w-md">
            <summary className="cursor-pointer mb-2">Error details</summary>
            <pre className="whitespace-pre-wrap text-left bg-gray-100 p-2 rounded">
              {this.state.error.message}
            </pre>
          </details>
          <button
            type="button"
            className="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
            onClick={() => this.setState({ hasError: false, error: undefined })}
          >
            Try again
          </button>
        </div>
      );
    }
 
    return this.props.children;
  }
}