diff --git a/web/src/App.jsx b/web/src/App.jsx
index 23d3118..6b99398 100644
--- a/web/src/App.jsx
+++ b/web/src/App.jsx
@@ -1,8 +1,9 @@
import { useEffect, useState } from "react";
-import { NavLink, Navigate, Route, Routes, useNavigate } from "react-router-dom";
+import { NavLink, Navigate, Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { api } from "./api";
import { useAuth } from "./auth";
import Icon from "./components/Icon";
+import ErrorBoundary from "./components/ErrorBoundary";
import BrandMark from "./components/BrandMark";
import Login from "./pages/Login";
import Dashboard from "./pages/Dashboard";
@@ -138,6 +139,7 @@ function StartFehler({ text, erneut }) {
function Protected({ children, adminOnly = false, wide = false }) {
const { user, isAdmin, loading, startFehler, erneutVersuchen } = useAuth();
+ const { pathname: pfad } = useLocation();
if (loading) return
Lädt…
;
if (startFehler) return ;
if (!user) return ;
@@ -147,7 +149,12 @@ function Protected({ children, adminOnly = false, wide = false }) {
{/* `wide` hebt die Lesebreite auf – nur fürs Dashboard-Raster sinnvoll. */}
-
{children}
+
+ {/* Je Seite eine eigene Grenze: stuerzt eine ab, bleibt wenigstens
+ die Navigation bedienbar. `key` setzt sie beim Seitenwechsel
+ zurueck, sonst haenge man nach einem Fehler dauerhaft fest. */}
+ {children}
+
);
diff --git a/web/src/components/ErrorBoundary.jsx b/web/src/components/ErrorBoundary.jsx
new file mode 100644
index 0000000..728722d
--- /dev/null
+++ b/web/src/components/ErrorBoundary.jsx
@@ -0,0 +1,74 @@
+import { Component } from "react";
+import Icon from "./Icon";
+
+/**
+ * Fängt Fehler beim Rendern ab.
+ *
+ * Ohne so eine Grenze hängt React den kompletten Baum aus, sobald irgendwo eine
+ * Ausnahme fliegt – die Seite wird schlagartig weiß und nur ein Neuladen hilft.
+ * Man sieht dann NICHT, was passiert ist, und kann es folglich auch nicht
+ * melden. Genau das war hier das Problem.
+ *
+ * Die Grenze zeigt deshalb die Meldung selbst an, nicht nur ein „Ups". Wer sie
+ * einmal sieht, kann sie weitergeben, und dann ist die Ursache in einer Minute
+ * gefunden statt in einer Stunde.
+ *
+ * `bereich` beschreibt, was gekapselt ist – für die Meldung.
+ */
+export default class ErrorBoundary extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { fehler: null, info: null };
+ }
+
+ static getDerivedStateFromError(fehler) {
+ return { fehler };
+ }
+
+ componentDidCatch(fehler, info) {
+ // React schreibt selbst schon in die Konsole; der Komponentenpfad hilft
+ // zusätzlich beim Einordnen.
+ console.error("Fehler beim Rendern:", fehler, info?.componentStack);
+ this.setState({ info });
+ }
+
+ render() {
+ const { fehler, info } = this.state;
+ if (!fehler) return this.props.children;
+
+ return (
+
+
+
+
+
+ {this.props.bereich ? `${this.props.bereich} konnte nicht angezeigt werden.` : "Etwas ist schiefgelaufen."}
+
+
+ {fehler.message || String(fehler)}
+
+
+
+
+
+
+
+
+
+ {/* Aufgeklappt nur auf Wunsch: die Angaben sind für einen Fehlerbericht
+ gedacht, nicht für den Alltag. */}
+
+ Technische Angaben
+