aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/ErrorBoundary.tsx
blob: 7f06085a4739035c488a8777e737294c7ca8f24a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { Component, type ReactNode } from "react";

interface ErrorBoundaryProps {
	children: ReactNode;
	fallback?: ReactNode;
}

interface ErrorBoundaryState {
	hasError: boolean;
	error: Error | null;
}

export class ErrorBoundary extends Component<
	ErrorBoundaryProps,
	ErrorBoundaryState
> {
	override state: ErrorBoundaryState = { hasError: false, error: null };

	static getDerivedStateFromError(error: Error): ErrorBoundaryState {
		return { hasError: true, error };
	}

	override render() {
		if (this.state.hasError) {
			return this.props.fallback ?? <ErrorFallback error={this.state.error} />;
		}
		return this.props.children;
	}
}

function ErrorFallback({ error }: { error: Error | null }) {
	return (
		<div
			role="alert"
			className="rounded-lg border border-red-200 bg-red-50 p-4"
		>
			<span className="text-sm text-red-600">
				{error?.message ?? "An error occurred"}
			</span>
		</div>
	);
}