fuzzyworld

when-am-i / files / src / components / ErrorBoundary.tsx

ErrorBoundary.tsx

1.5 KB · history · blame

1import React from 'react';
2import { reportMailtoHref } from '../utils/report';
3
4interface Props {
5 children: React.ReactNode;
6}
7
8interface State {
9 error: Error | null;
10}
11
12// Catches render-time errors anywhere below it and shows a recoverable fallback
13// with a prefilled error report link (async errors are caught by the global
14// handlers in report.ts instead).
15class ErrorBoundary extends React.Component<Props, State> {
16 state: State = { error: null };
17
18 static getDerivedStateFromError(error: Error): State {
19 return { error };
20 }
21
22 componentDidCatch(error: Error, info: React.ErrorInfo): void {
23 console.error('[when-am-i] render error:', error, info);
24 }
25
26 render(): React.ReactNode {
27 const { error } = this.state;
28 if (!error) return this.props.children;
29
30 return (
31 <div
32 role="alert"
33 style={{ padding: 24, maxWidth: 640, margin: '40px auto', fontFamily: 'sans-serif' }}
34 >
35 <h2>Something went wrong</h2>
36 <p>Sorry — the app hit an unexpected error. You can help by sending a report.</p>
37 <p style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
38 <a href={reportMailtoHref(error)}>Send an error report</a>
39 <button type="button" onClick={() => window.location.reload()}>
40 Reload
41 </button>
42 </p>
43 </div>
44 );
45 }
46}
47
48export { ErrorBoundary };