Files
SlpSoftware/src/components/ErrorBoundary.tsx
T

45 lines
1.3 KiB
TypeScript

import { Component } from 'react';
import type { ErrorInfo, ReactNode } from 'react';
import * as Sentry from '@sentry/react';
interface ErrorBoundaryProps {
children: ReactNode;
}
interface ErrorBoundaryState {
hasError: boolean;
}
/**
* Top-level, on-brand error boundary (NFR Design resilience pattern; SECURITY-09/SECURITY-15).
* Shows a generic, themed fallback message — never technical details like stack traces.
*/
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
state: ErrorBoundaryState = { hasError: false };
static getDerivedStateFromError(): ErrorBoundaryState {
return { hasError: true };
}
componentDidCatch(error: Error, info: ErrorInfo): void {
console.error('Unexpected application error', error, info);
Sentry.captureException(error, { extra: { componentStack: info.componentStack } });
}
render(): ReactNode {
if (this.state.hasError) {
return (
<div
className="theme-red flex min-h-screen items-center justify-center bg-bg px-6 text-center text-text"
role="alert"
data-testid="error-boundary-fallback"
>
<p className="font-display text-lg">Er ging iets mis. Probeer de pagina te vernieuwen.</p>
</div>
);
}
return this.props.children;
}
}