import React, { Component, ErrorInfo, ReactNode } from 'react'; import { mdiAlertCircle } from '@mdi/js'; import BaseIcon from './BaseIcon'; // Define the props and state interfaces interface ErrorBoundaryProps { children: ReactNode; } interface ErrorBoundaryState { hasError: boolean; error: Error | null; errorInfo: ErrorInfo | null; showStack: boolean; } // Class-based ErrorBoundary Component class ErrorBoundary extends Component { constructor(props: ErrorBoundaryProps) { super(props); // Define state variables this.state = { hasError: false, error: null, errorInfo: null, showStack: false, }; } static getDerivedStateFromError(error: Error): Partial { // Update state so the next render will show the fallback UI return { hasError: true, error: error, }; } componentDidUpdate( prevProps: Readonly, prevState: Readonly, snapshot?: any, ) { console.log('componentDidUpdate'); } async componentWillUnmount() { console.log('componentWillUnmount'); const response = await fetch('/api/logError', { method: 'DELETE', }); const data = await response.json(); console.log('Error logs cleared:', data); } async componentDidCatch(error: Error, errorInfo: ErrorInfo) { console.log('Error caught in boundary:', error, errorInfo); // Update state with error details this.setState({ errorInfo: errorInfo, }); // Function to log errors to the server const logErrorToServer = async () => { try { const response = await fetch('/api/logError', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ message: error.message, stack: errorInfo.componentStack, }), }); const data = await response.json(); console.log('Error logged:', data); } catch (err) { console.error('Failed to log error:', err); } }; // Function to fetch logged errors (optional) const fetchLoggedErrors = async () => { try { const response = await fetch('/api/logError'); const data = await response.json(); console.log('Fetched logs:', data); } catch (err) { console.error('Failed to fetch logs:', err); } }; await logErrorToServer(); await fetchLoggedErrors(); } toggleStack = () => { this.setState((prevState) => ({ showStack: !prevState.showStack, })); }; resetError = () => { this.setState({ hasError: false, error: null, errorInfo: null, showStack: false, }); }; tryAgain = async () => { try { const response = await fetch('/api/logError', { method: 'DELETE', }); const data = await response.json(); console.log('Error logs cleared:', data); } catch (e) { console.error('Failed to clear error logs:', e); } this.setState({ hasError: false }); }; render() { if (this.state.hasError) { // Extract error details const { error, errorInfo, showStack } = this.state; const errorMessage = error?.message || 'An unexpected error occurred'; const stackTrace = errorInfo?.componentStack || error?.stack || 'No stack trace available'; return (

Something went wrong

We're sorry, but we encountered an unexpected error.

{errorMessage}

{showStack && (
                      {stackTrace}
                    
)}
); } return this.props.children; } } export default ErrorBoundary;