- Create ErrorBoundary component to handle React render errors - Wrap App component with ErrorBoundary for global error handling - Add comprehensive tests for ErrorBoundary functionality - Show fallback UI with error message when errors occur
63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
/**
|
|
* React error boundary component.
|
|
*
|
|
* Catches render-time exceptions in child components and shows a fallback UI.
|
|
*/
|
|
import React from "react";
|
|
|
|
interface ErrorBoundaryState {
|
|
hasError: boolean;
|
|
errorMessage: string | null;
|
|
}
|
|
|
|
interface ErrorBoundaryProps {
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
constructor(props: ErrorBoundaryProps) {
|
|
super(props);
|
|
this.state = { hasError: false, errorMessage: null };
|
|
this.handleReload = this.handleReload.bind(this);
|
|
}
|
|
|
|
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
|
return { hasError: true, errorMessage: error.message || "Unknown error" };
|
|
}
|
|
|
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {
|
|
console.error("ErrorBoundary caught an error", { error, errorInfo });
|
|
}
|
|
|
|
handleReload(): void {
|
|
window.location.reload();
|
|
}
|
|
|
|
render(): React.ReactNode {
|
|
if (this.state.hasError) {
|
|
return (
|
|
<div
|
|
style={{
|
|
display: "flex",
|
|
flexDirection: "column",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
minHeight: "100vh",
|
|
padding: "24px",
|
|
textAlign: "center",
|
|
}}
|
|
role="alert"
|
|
>
|
|
<h1>Something went wrong</h1>
|
|
<p>{this.state.errorMessage ?? "Please try reloading the page."}</p>
|
|
<button type="button" onClick={this.handleReload} style={{ marginTop: "16px" }}>
|
|
Reload
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return this.props.children;
|
|
}
|
|
}
|