diff --git a/.phase4-state.json b/.phase4-state.json index 8eabbf7..5da2fd5 100644 --- a/.phase4-state.json +++ b/.phase4-state.json @@ -1,7 +1,8 @@ { "completed_features": [ - "admin-user-management" + "admin-user-management", + "csv-export-time-entries" ], - "current_feature": "csv-export-time-entries", + "current_feature": "error-boundary", "started_at": "2026-05-23T05:10:51.482879" } \ No newline at end of file diff --git a/GENERATION_LOG.md b/GENERATION_LOG.md index a43efe2..5c33772 100644 --- a/GENERATION_LOG.md +++ b/GENERATION_LOG.md @@ -483,3 +483,15 @@ undefined - `05:15:03` **INFO** wrote 8846 chars in 71.0s (attempt 1) - `05:15:03` **INFO** Running tsc --noEmit on api… - `05:15:04` **INFO** tsc clean ✓ +- `05:15:04` **INFO** Committed feature csv-export-time-entries +- `05:15:05` **INFO** Pushed: rc=0 + +## Phase-3 Feature: error-boundary (2026-05-23 05:15:05) + +- `05:15:05` **INFO** Description: React ErrorBoundary + global wrapping in App.tsx +- `05:15:05` **INFO** Generating apps/web/src/components/ErrorBoundary.tsx (React-ErrorBoundary class-component. Fängt unkaufgefangene Render-Erro…) +- `05:15:26` **INFO** wrote 2338 chars in 21.9s (attempt 1) +- `05:15:26` **INFO** Generating apps/web/src/App.tsx (ERWEITERT — wrap RouterProvider in . Behalte ToastProvi…) +- `05:15:45` **INFO** wrote 2176 chars in 18.3s (attempt 1) +- `05:15:45` **INFO** Running tsc --noEmit on api… +- `05:15:46` **INFO** tsc clean ✓ diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 1fdbfbb..28066e6 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -7,6 +7,7 @@ import Projects from "./pages/Projects" import Profile from "./pages/Profile" import Nav from "./components/Nav" import { ToastProvider } from "./components/Toast" +import ErrorBoundary from "./components/ErrorBoundary" import { api } from "./lib/api" const rootRoute = createRootRoute({ @@ -92,7 +93,9 @@ declare module "@tanstack/react-router" { export default function App() { return ( - + + + ) } \ No newline at end of file diff --git a/apps/web/src/components/ErrorBoundary.tsx b/apps/web/src/components/ErrorBoundary.tsx new file mode 100644 index 0000000..2c179b1 --- /dev/null +++ b/apps/web/src/components/ErrorBoundary.tsx @@ -0,0 +1,74 @@ +import React, { Component, ErrorInfo, ReactNode } from 'react'; + +interface Props { + children: ReactNode; +} + +interface State { + hasError: boolean; + error: Error | null; +} + +export default class ErrorBoundary extends Component { + constructor(props: Props) { + super(props); + this.state = { hasError: false, error: null }; + } + + static getDerivedStateFromError(error: Error): State { + return { hasError: true, error }; + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo) { + console.error('ErrorBoundary caught an error:', error, errorInfo); + } + + handleReload = () => { + window.location.reload(); + }; + + render() { + if (this.state.hasError) { + return ( +
+
+
+
+ + + +
+
+ +

+ Etwas ist schiefgelaufen +

+ +

+ {this.state.error?.message || 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es erneut.'} +

+ + +
+
+ ); + } + + return this.props.children; + } +} \ No newline at end of file