aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/client/components/ErrorBoundary.tsx
blob: a86ea9a0fa7526cd8b040d6d2a79b78381dfb05c (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="bg-error/5 border border-error/20 rounded-xl p-4"
		>
			<span className="text-error">
				{error?.message ?? "An error occurred"}
			</span>
		</div>
	);
}