promptenhancer / src /components /ErrorBoundary.tsx
Tobs248's picture
# Rolle
eee3ce2 verified
Raw
History Blame Contribute Delete
3.98 kB
tsx
import React, { Component, ErrorInfo, ReactNode } from 'react'
import { AlertTriangle, RefreshCw } from 'lucide-react'
/**
* Props for the ErrorBoundary component
*/
interface ErrorBoundaryProps {
children: ReactNode
}
/**
* State for the ErrorBoundary component
*/
interface ErrorBoundaryState {
hasError: boolean
error: Error | null
errorInfo: ErrorInfo | null
}
/**
* Error Boundary component to catch and handle React errors gracefully
* Provides user-friendly error messages and recovery options
*/
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = {
hasError: false,
error: null,
errorInfo: null
}
}
/**
* Static method to catch errors and update state
*/
static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
return {
hasError: true,
error
}
}
/**
* ComponentDidCatch to log error details
*/
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('ErrorBoundary caught an error:', error, errorInfo)
this.setState({
error,
errorInfo
})
// In a real app, you might want to send this to an error reporting service
// reportError(error, errorInfo)
}
/**
* Handle retry after error
*/
handleRetry = () => {
this.setState({
hasError: false,
error: null,
errorInfo: null
})
}
/**
* Handle refresh page
*/
handleRefresh = () => {
window.location.reload()
}
render() {
if (this.state.hasError) {
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center px-4">
<div className="max-w-md w-full bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 p-8 text-center">
<div className="w-16 h-16 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center mx-auto mb-6">
<AlertTriangle className="w-8 h-8 text-red-600 dark:text-red-400" />
</div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-4">
Etwas ist schiefgelaufen
</h1>
<p className="text-gray-600 dark:text-gray-400 mb-6">
Es ist ein unerwarteter Fehler aufgetreten. Bitte versuche es erneut oder lade die Seite neu.
</p>
{process.env.NODE_ENV === 'development' && this.state.error && (
<details className="text-left mb-6 p-4 bg-gray-100 dark:bg-gray-700 rounded-lg text-sm">
<summary className="cursor-pointer font-medium text-gray-900 dark:text-gray-100 mb-2">
Technische Details (Entwicklungsmodus)
</summary>
<pre className="text-xs text-red-600 dark:text-red-400 overflow-auto">
{this.state.error.toString()}
{this.state.errorInfo?.componentStack}
</pre>
</details>
)}
<div className="flex flex-col sm:flex-row gap-3">
<button
onClick={this.handleRetry}
className="flex-1 btn-primary flex items-center justify-center gap-2"
>
<RefreshCw className="w-4 h-4" />
Erneut versuchen
</button>
<button
onClick={this.handleRefresh}
className="flex-1 btn-secondary"
>
Seite neu laden
</button>
</div>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-4">
Falls das Problem besteht, kontaktiere bitte den Support.
</p>
</div>
</div>
)
}
return this.props.children
}
}
</html>