/* Kundenansicht neu: ein einziger Zugang zur Schnittstelle des Portals. Fehler kommen immer als ApiFehler (mit Status, Code, Text, Feld und dem ganzen Body), Netzfehler mit Status 0. */ const TEXT_NETZ = 'Keine Verbindung. Bitte versuch es gleich noch einmal.' const TEXT_502 = 'Server nicht erreichbar. Bitte kurz warten und noch einmal versuchen.' // Sitzung beendet (Passwort auf einem anderen Gerät geändert): nur einmal zur Anmeldung wechseln let sitzungBeendetGemeldet = false export class ApiFehler extends Error { constructor(message, { status = 0, code = '', field = '', body = {} } = {}) { super(message) this.name = 'ApiFehler' this.status = status this.code = code this.field = field this.body = body } } /** Aufruf der Schnittstelle. `roh` ist ein Rohdaten-Body (Blob, ArrayBuffer …), der unverändert als application/octet-stream geht. */ export async function api(pfad, { method = 'GET', body, roh } = {}) { const headers = {} let inhalt if (roh) { headers['Content-Type'] = 'application/octet-stream' inhalt = roh } else if (body !== undefined && body !== null) { headers['Content-Type'] = 'application/json' inhalt = JSON.stringify(body) } let antwort try { antwort = await fetch(pfad, { method, credentials: 'same-origin', headers, body: inhalt }) } catch { // Netzfehler (offline, Server nicht erreichbar): deutscher Text statt „Failed to fetch“; Status 0 = nie eine Antwort bekommen throw new ApiFehler(TEXT_NETZ, { status: 0 }) } const daten = await antwort.json().catch(() => ({})) if (antwort.ok) return daten const antwortBody = daten !== null && typeof daten === 'object' && !Array.isArray(daten) ? daten : {} const message = typeof antwortBody.error === 'string' && antwortBody.error ? antwortBody.error : (antwort.status === 502 ? TEXT_502 : `Fehler ${antwort.status}`) const fehler = new ApiFehler(message, { status: antwort.status, code: typeof antwortBody.code === 'string' ? antwortBody.code : '', field: typeof antwortBody.field === 'string' ? antwortBody.field : '', body: antwortBody, }) if (fehler.code === 'session_revoked' && !sitzungBeendetGemeldet) { sitzungBeendetGemeldet = true window.location.href = `/login.html?error=${encodeURIComponent(message)}` } throw fehler }