Kundenansicht neu P1: h(), api() mit ApiFehler und Quelltext-Regel
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
46edb7c418
commit
6f0808647f
4 files changed
+140
No files matched your search
@@ -0,0 +1,54 @@
|
||||
/* 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
|
||||
}
|
||||
Reference in new issue
Block a user