import { Component, ErrorInfo, ReactNode, createRef } from 'react'; import { RefreshCw } from 'lucide-react'; import { Button } from '../Button'; import { logger } from '~/utils'; import { useLocalize } from '~/hooks'; /** * Error boundary specifically for DataTable component. * Catches JavaScript errors in the table rendering and provides a fallback UI. * Handles errors from virtualizer, cell renderers, fetch operations, and child components. */ interface DataTableErrorBoundaryState { hasError: boolean; error?: Error; } interface DataTableErrorBoundaryProps { children: ReactNode; onError?: (error: Error) => void; onReset?: () => void; } interface DataTableErrorBoundaryInnerProps extends DataTableErrorBoundaryProps { localize: ReturnType; } class DataTableErrorBoundaryInner extends Component< DataTableErrorBoundaryInnerProps, DataTableErrorBoundaryState > { private errorCardRef = createRef(); constructor(props: DataTableErrorBoundaryInnerProps) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error: Error): DataTableErrorBoundaryState { return { hasError: true, error }; } componentDidCatch(error: Error, errorInfo: ErrorInfo) { logger.error('DataTable Error Boundary caught an error:', error, errorInfo); this.props.onError?.(error); } componentDidUpdate( _prevProps: DataTableErrorBoundaryInnerProps, prevState: DataTableErrorBoundaryState, ) { if (!prevState.hasError && this.state.hasError && this.errorCardRef.current) { this.errorCardRef.current.focus(); } } /** * Reset the error state and attempt to re-render the children. * This can be used to retry after a table error (e.g., network retry). */ private handleReset = () => { this.setState({ hasError: false, error: undefined }); this.props.onReset?.(); }; render() { if (this.state.hasError) { return (

{this.props.localize('com_ui_table_error')}

{this.props.localize('com_ui_table_error_description')}

{import.meta.env.MODE === 'development' && this.state.error && (
{this.props.localize('com_ui_error_details')}
                {this.state.error.message}
              
)}
); } return this.props.children; } } export function DataTableErrorBoundary(props: DataTableErrorBoundaryProps) { const localize = useLocalize(); return ; } export default DataTableErrorBoundary;