From f97ceab3ad68496aa5a3d4a1fc64e3fa255558f1 Mon Sep 17 00:00:00 2001 From: Tobi G Date: Tue, 25 Aug 2026 22:04:06 +0200 Subject: [PATCH] companion-app: Fehlergrenze um die App - Absturz sichtbar statt schwarzer Seite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ohne React-Error-Boundary unmountet ein unbehandelter Renderfehler die gesamte App; übrig bleibt nur der Seitenhintergrund (im Nacht-Theme praktisch schwarz) - passt zum gemeldeten "schwarze Seite nach Update prüfen". Behebt nicht die eigentliche Ursache, macht einen künftigen Absturz aber sichtbar (Fehlertext, Neu-laden-Knopf) und loggt ihn in die Konsole statt ihn stumm verschwinden zu lassen. Co-Authored-By: Claude Sonnet 5 --- companion-app/src/ErrorGrenze.tsx | 51 +++++++++++++++++++++++++++++++ companion-app/src/main.tsx | 5 ++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 companion-app/src/ErrorGrenze.tsx diff --git a/companion-app/src/ErrorGrenze.tsx b/companion-app/src/ErrorGrenze.tsx new file mode 100644 index 0000000..cca2f64 --- /dev/null +++ b/companion-app/src/ErrorGrenze.tsx @@ -0,0 +1,51 @@ +/** + * Auffangnetz für Abstürze irgendwo im Baum. + * + * Ohne diese Grenze unmountet React die gesamte App bei jedem unbehandelten + * Fehler beim Rendern - #wurzel bleibt leer, und übrig bleibt nur der + * Seitenhintergrund (im Nacht-Theme praktisch schwarz). Genau das wurde als + * "schwarze Seite nach Update prüfen" gemeldet: kein hängender Ladezustand, + * sondern ein stiller Absturz, dessen eigentliche Fehlermeldung nirgends + * ankam. Ein "zurück und wieder rein" half nur, weil das erneute Öffnen den + * Baum komplett neu aufbaut und der auslösende Zustand dabei verschwindet. + * + * Diese Grenze behebt nicht die eigentliche Ursache - sie sorgt nur dafür, + * dass ein Absturz ab jetzt sichtbar ist (Fehlertext, Neu-laden-Knopf) statt + * unsichtbar zu bleiben, und dass der Fehlertext in der Konsole landet, um + * die eigentliche Ursache beim nächsten Mal fassen zu können. + */ + +import { Component, type ReactNode } from "react" + +import { ActionButton } from "@audi-dash/ui" + +export class ErrorGrenze extends Component< + { children: ReactNode }, + { fehler: Error | null } +> { + state: { fehler: Error | null } = { fehler: null } + + static getDerivedStateFromError(fehler: Error) { + return { fehler } + } + + componentDidCatch(fehler: Error, info: { componentStack?: string | null }) { + console.error("ErrorGrenze: unbehandelter Fehler beim Rendern", fehler, info.componentStack) + } + + render() { + if (!this.state.fehler) return this.props.children + return ( +
+ Etwas ist schiefgelaufen +

+ Die Seite konnte nicht dargestellt werden. Ein Neuladen behebt das in der Regel. +

+

+ {this.state.fehler.message} +

+ window.location.reload()}>Neu laden +
+ ) + } +} diff --git a/companion-app/src/main.tsx b/companion-app/src/main.tsx index bcbd8dc..a3a0182 100644 --- a/companion-app/src/main.tsx +++ b/companion-app/src/main.tsx @@ -6,6 +6,7 @@ import "./stile/grundlage.css" import "./stile/audi-schrift.css" import { nativeAblageEinrichten } from "./api" import { App } from "./App" +import { ErrorGrenze } from "./ErrorGrenze" // In der nativen Hülle den Token in den Schlüsselbund legen statt in // localStorage. Ohne Hülle passiert hier nichts. @@ -16,6 +17,8 @@ if (!wurzel) throw new Error("Wurzelelement #wurzel fehlt in index.html") createRoot(wurzel).render( - + + + , )