peijun1's picture
Deploy AI Studio Proxy API to Hugging Face Spaces
a5784e9
Raw
History Blame Contribute Delete
2.26 kB
/**
* Error Boundary Component
* Catches React errors and displays fallback UI
* Note: Class components can't use hooks, so we accept translations as props
*/
import { Component, type ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
name?: string;
}
interface State {
hasError: boolean;
error: Error | null;
}
// Default messages (will be in English as fallback)
const defaultMessages = {
failed: 'failed to load',
unknownError: 'Unknown error',
retry: 'Retry',
};
export class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
console.error(`[ErrorBoundary${this.props.name ? `: ${this.props.name}` : ''}]`, error, errorInfo);
}
render(): ReactNode {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return (
<div style={{
padding: '1rem',
margin: '1rem',
borderRadius: '0.5rem',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
border: '1px solid rgba(239, 68, 68, 0.3)',
color: '#ef4444',
}}>
<h3 style={{ margin: '0 0 0.5rem 0', fontSize: '0.9rem' }}>
{this.props.name || 'Component'} {defaultMessages.failed}
</h3>
<p style={{ margin: 0, fontSize: '0.8rem', opacity: 0.8 }}>
{this.state.error?.message || defaultMessages.unknownError}
</p>
<button
onClick={() => this.setState({ hasError: false, error: null })}
style={{
marginTop: '0.5rem',
padding: '0.25rem 0.5rem',
fontSize: '0.75rem',
borderRadius: '0.25rem',
backgroundColor: 'rgba(239, 68, 68, 0.2)',
color: '#ef4444',
border: 'none',
cursor: 'pointer',
}}
>
{defaultMessages.retry}
</button>
</div>
);
}
return this.props.children;
}
}