supersam/src/components/ErrorBoundary.jsx

80 lines
1.9 KiB
JavaScript

import React from 'react';
import { logError } from '../utils/errorLogger';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Extract component stack for richer context
const componentInfo = {
component: errorInfo?.componentStack || null,
props: this.props,
};
logError(error, componentInfo);
}
handleRetry = () => {
this.setState({ hasError: false, error: null });
};
renderDefaultFallback() {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
padding: '2rem',
textAlign: 'center',
minHeight: '200px',
}}
>
<h2 style={{ marginBottom: '0.5rem', color: '#e53e3e' }}>
Something went wrong
</h2>
<p style={{ marginBottom: '1rem', color: '#718096', fontSize: '0.9rem' }}>
An unexpected error occurred. You can try again.
</p>
<button
onClick={this.handleRetry}
style={{
padding: '0.5rem 1.25rem',
fontSize: '0.9rem',
fontWeight: 600,
color: '#fff',
backgroundColor: '#3182ce',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
}}
>
Try Again
</button>
</div>
);
}
render() {
if (this.state.hasError) {
// Allow custom fallback render function
if (typeof this.props.fallback === 'function') {
return this.props.fallback(this.state.error, this.handleRetry);
}
return this.renderDefaultFallback();
}
return this.props.children;
}
}
export default ErrorBoundary;