64 lines
2 KiB
JavaScript
64 lines
2 KiB
JavaScript
import React from 'react';
|
||
|
||
class ErrorBoundary extends React.Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = { hasError: false, error: null, errorInfo: null };
|
||
}
|
||
|
||
static getDerivedStateFromError(error) {
|
||
return { hasError: true };
|
||
}
|
||
|
||
componentDidCatch(error, errorInfo) {
|
||
console.error('🔴 Error caught by boundary:', error);
|
||
console.error('Error info:', errorInfo);
|
||
this.setState({
|
||
error,
|
||
errorInfo
|
||
});
|
||
}
|
||
|
||
render() {
|
||
if (this.state.hasError) {
|
||
return (
|
||
<div style={{ padding: '40px', fontFamily: 'monospace', maxWidth: '800px', margin: '0 auto' }}>
|
||
<h1 style={{ color: '#ef4444' }}>⚠️ Something went wrong</h1>
|
||
<details style={{ whiteSpace: 'pre-wrap', background: '#1e293b', padding: '20px', borderRadius: '8px', color: '#e2e8f0' }}>
|
||
<summary style={{ cursor: 'pointer', marginBottom: '10px', fontSize: '16px', fontWeight: 'bold' }}>
|
||
Error Details (click to expand)
|
||
</summary>
|
||
<div style={{ marginTop: '10px' }}>
|
||
<strong>Error:</strong>
|
||
<pre style={{ marginTop: '5px', color: '#fca5a5' }}>{this.state.error && this.state.error.toString()}</pre>
|
||
|
||
<strong style={{ marginTop: '20px', display: 'block' }}>Stack Trace:</strong>
|
||
<pre style={{ marginTop: '5px', fontSize: '12px', color: '#cbd5e1' }}>
|
||
{this.state.errorInfo && this.state.errorInfo.componentStack}
|
||
</pre>
|
||
</div>
|
||
</details>
|
||
<button
|
||
onClick={() => window.location.reload()}
|
||
style={{
|
||
marginTop: '20px',
|
||
padding: '10px 20px',
|
||
background: '#3b82f6',
|
||
color: 'white',
|
||
border: 'none',
|
||
borderRadius: '6px',
|
||
cursor: 'pointer',
|
||
fontSize: '14px'
|
||
}}
|
||
>
|
||
Reload Page
|
||
</button>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
return this.props.children;
|
||
}
|
||
}
|
||
|
||
export default ErrorBoundary;
|