@@ -0,0 +1,68 @@
|
||||
import { AlertTriangle, RefreshCw } from 'lucide-react';
|
||||
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
||||
import log from 'electron-log/renderer';
|
||||
|
||||
import TextButton from './styled/TextButton';
|
||||
|
||||
type Props = {
|
||||
tabName: string;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
type State = {
|
||||
error?: Error;
|
||||
componentStack?: string;
|
||||
};
|
||||
|
||||
class TabErrorBoundary extends Component<Props, State> {
|
||||
state: State = {};
|
||||
|
||||
static getDerivedStateFromError(error: Error): State {
|
||||
return { error };
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
log.error(`Tab "${this.props.tabName}" crashed:`, error, info);
|
||||
this.setState({ error, componentStack: info.componentStack ?? undefined });
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
if (prevProps.tabName !== this.props.tabName) {
|
||||
this.setState({ error: undefined, componentStack: undefined });
|
||||
}
|
||||
}
|
||||
|
||||
#reset = () => this.setState({ error: undefined, componentStack: undefined });
|
||||
|
||||
render() {
|
||||
if (!this.state.error) return this.props.children;
|
||||
const { error, componentStack } = this.state;
|
||||
return (
|
||||
<div className="tw-surface flex min-h-0 flex-grow flex-col gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<AlertTriangle size={22} className="text-red" />
|
||||
<h4 className="text-red">{this.props.tabName} crashed</h4>
|
||||
</div>
|
||||
<hr />
|
||||
<p className="text-white">
|
||||
{error.name}: {error.message}
|
||||
</p>
|
||||
{componentStack && (
|
||||
<pre className="s1 max-h-[200px] overflow-auto whitespace-pre-wrap text-blueGray">
|
||||
{componentStack.trim()}
|
||||
</pre>
|
||||
)}
|
||||
<hr />
|
||||
<TextButton
|
||||
icon={RefreshCw}
|
||||
onClick={this.#reset}
|
||||
className="self-end text-warmGreen"
|
||||
>
|
||||
Try again
|
||||
</TextButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TabErrorBoundary;
|
||||
Reference in New Issue
Block a user