diff --git a/client/components/ErrorBoundary.tsx b/client/components/ErrorBoundary.tsx new file mode 100644 index 00000000..8d4a6379 --- /dev/null +++ b/client/components/ErrorBoundary.tsx @@ -0,0 +1,81 @@ +import React, { Component, ErrorInfo, ReactNode } from 'react'; +import { Alert, AlertDescription } from '@/components/ui/alert'; +import { Button } from '@/components/ui/button'; +import { AlertTriangle, RefreshCw } from 'lucide-react'; + +interface Props { + children: ReactNode; +} + +interface State { + hasError: boolean; + error?: Error; + errorInfo?: ErrorInfo; +} + +class ErrorBoundary extends Component { + public state: State = { + hasError: false + }; + + public static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + public componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('Uncaught error:', error, errorInfo); + this.setState({ error, errorInfo }); + } + + private handleReload = () => { + window.location.reload(); + }; + + private handleReset = () => { + this.setState({ hasError: false, error: undefined, errorInfo: undefined }); + }; + + public render() { + if (this.state.hasError) { + return ( +
+
+ + + +
+

Something went wrong

+

+ An error occurred while rendering the application. This is usually temporary. +

+ {this.state.error && ( +
+ Error details +
+                        {this.state.error.message}
+                      
+
+ )} +
+
+
+ +
+ + +
+
+
+ ); + } + + return this.props.children; + } +} + +export default ErrorBoundary;