fix(boxwart): unbekannte /api-Pfade sind 404, Waechter nennt die echte Fehlerursache
Ampel / ampel (push) Failing after 21s
Ampel / ampel (push) Failing after 21s
- Der SPA-Rueckfall lieferte fuer unbekannte /api-Pfade die Startseite (HTML, 200). Im
ersten Probelauf stuerzte der Start daran ab (/api/radar gab es noch nicht). Jetzt 404;
api() behandelt Nicht-JSON als Fehler, der Router zeigt eine deutsche Fehleranzeige.
- Waechter: Skriptmeldungen ("! ...", fehlgeschlagen) gehen vor systemd-Rahmenzeilen wie
"Failed to start ..." - die sagen nur, dass es scheiterte, nicht warum.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bfb07a92c3
commit
f3af2adec3
@@ -0,0 +1,18 @@
|
||||
import type { ErrorComponentProps } from "@tanstack/react-router"
|
||||
|
||||
/** Deutsche Fehleranzeige einer Ansicht statt „Something went wrong!“. */
|
||||
export function Absturz({ error }: ErrorComponentProps) {
|
||||
return (
|
||||
<div role="alert" className="flex flex-col items-start gap-3 rounded-2xl border border-rot-rand bg-rot-grund p-6 text-rot-text">
|
||||
<p className="schild text-lg text-rot">Diese Ansicht ist abgestürzt</p>
|
||||
<p className="text-[15px]">{error instanceof Error ? error.message : String(error)}</p>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => window.location.reload()}
|
||||
className="schild h-11 rounded-lg border border-rot-rand px-5 text-sm text-foreground hover:bg-[#3a1512]"
|
||||
>
|
||||
Neu laden
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createRootRoute, createRoute, createRouter, lazyRouteComponent, Navigate } from "@tanstack/react-router"
|
||||
import { Absturz } from "./Absturz"
|
||||
import { Shell } from "./Shell"
|
||||
import { StartSeite } from "@/views/Start"
|
||||
|
||||
@@ -25,6 +26,7 @@ const modelle = createRoute({
|
||||
export const router = createRouter({
|
||||
routeTree: wurzel.addChildren([start, updates, modelle]),
|
||||
defaultPreload: "intent",
|
||||
defaultErrorComponent: Absturz,
|
||||
})
|
||||
|
||||
declare module "@tanstack/react-router" {
|
||||
|
||||
@@ -34,6 +34,9 @@ export async function api<T>(pfad: string, init: RequestInit = {}): Promise<T> {
|
||||
const text = await antwort.text()
|
||||
const body = text ? safeJson(text) : null
|
||||
if (!antwort.ok) throw new ApiFehler(antwort.status, detailAus(body, antwort.status))
|
||||
// Kommt statt JSON eine HTML-Seite (alter Server, falscher Pfad), ist das ein Fehler —
|
||||
// sonst rechnen die Ansichten mit einem Text, als wären es Daten.
|
||||
if (typeof body === "string") throw new ApiFehler(antwort.status, "Die Box antwortet nicht mit Daten.")
|
||||
return body as T
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ function Instrumente({ box }: { box: Start["box"] }) {
|
||||
const RADAR_ART = { bestanden: "gruen", durchgefallen: "rot", wartet: "cyan", neu: "cyan" } as const
|
||||
|
||||
function RadarKasten({ radar }: { radar: Radar | undefined }) {
|
||||
if (!radar) return null
|
||||
if (!radar?.kandidaten) return null
|
||||
const offen = radar.kandidaten.filter((k) => ["bestanden", "wartet", "neu"].includes(k.status))
|
||||
const vorn = offen.find((k) => k.status === "bestanden") ?? offen[0]
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user