diff --git a/web/components/error-boundary.tsx b/web/components/error-boundary.tsx new file mode 100644 index 00000000..f2d99be4 --- /dev/null +++ b/web/components/error-boundary.tsx @@ -0,0 +1,69 @@ +import {Component, ErrorInfo, ReactNode} from 'react' +import {Button} from 'web/components/buttons/button' + +interface Props { + children?: ReactNode + fallback?: ReactNode +} + +interface State { + hasError: boolean + error?: Error +} + +export class ErrorBoundary extends Component { + constructor(props: Props) { + super(props) + this.state = {hasError: false} + } + + static getDerivedStateFromError(error: Error): State { + return {hasError: true, error} + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('ErrorBoundary caught an error:', error, errorInfo) + } + + handleReset = () => { + this.setState({hasError: false, error: undefined}) + window.location.reload() + } + + render() { + if (this.state.hasError) { + if (this.props.fallback) { + return this.props.fallback + } + + return ( +
+
+

Something went wrong

+

+ We apologize for the inconvenience. An unexpected error occurred. +

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