Nicht jede erfolgreiche Antwort hat einen Körper
Bei jedem Scanstart stand in der Verwaltung "JSON.parse: unexpected end of data" — eine Fehlermeldung für etwas, das tadellos funktioniert hatte. Gemessen: der Scan-Endpunkt antwortet mit 202 Accepted, Content-Length 0 und ohne Content-Type. Er läuft im Hintergrund weiter, da gibt es noch nichts zu melden. Der Abruf-Helfer behandelte aber nur 204 als leer und liess JSON.parse auf eine leere Zeichenkette los. Jetzt entscheidet der Inhalt, nicht der Status. Eine Liste von Status-Codes wäre wieder eine, die beim nächsten Endpunkt unvollständig ist. Dazu: die Zeile "Metadaten" nannte die Sprache ein zweites Mal, obwohl sie seit kurzem eine eigene Zeile hat. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
98565e14b5
commit
b64497acd5
+23
-1
@@ -207,7 +207,29 @@ async function anfrage<T>(pfad: string, opts: RequestInit = {}): Promise<T> {
|
|||||||
throw new ApiFehler(antwort.status, text);
|
throw new ApiFehler(antwort.status, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return antwort.status === 204 ? (undefined as T) : antwort.json();
|
// **Nicht jede erfolgreiche Antwort hat einen Körper.**
|
||||||
|
//
|
||||||
|
// Vorher galt das nur für 204. Der Scan antwortet aber mit 202 Accepted und
|
||||||
|
// ohne Inhalt — er läuft im Hintergrund weiter, da gibt es noch nichts zu
|
||||||
|
// melden. `JSON.parse` lief dann auf eine leere Zeichenkette, und in der
|
||||||
|
// Verwaltung stand bei jedem Scanstart „unexpected end of data": eine
|
||||||
|
// Fehlermeldung für etwas, das tadellos funktioniert hatte.
|
||||||
|
//
|
||||||
|
// Geprüft wird der Inhalt, nicht der Status. Eine Liste von Status-Codes
|
||||||
|
// wäre wieder eine, die beim nächsten Endpunkt unvollständig ist.
|
||||||
|
if (antwort.status === 204 || antwort.status === 205) return undefined as T;
|
||||||
|
|
||||||
|
const laenge = antwort.headers.get('Content-Length');
|
||||||
|
const art = antwort.headers.get('Content-Type') ?? '';
|
||||||
|
if (laenge === '0' || !art.includes('json')) {
|
||||||
|
// Ohne `Content-Length` — etwa bei Chunked-Übertragung — entscheidet der
|
||||||
|
// Text selbst.
|
||||||
|
const text = await antwort.text();
|
||||||
|
if (text.trim().length === 0) return undefined as T;
|
||||||
|
return JSON.parse(text) as T;
|
||||||
|
}
|
||||||
|
|
||||||
|
return antwort.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Bilder ---------- */
|
/* ---------- Bilder ---------- */
|
||||||
|
|||||||
@@ -872,8 +872,9 @@ function serverbereich(geaendert: () => void): HTMLElement {
|
|||||||
|
|
||||||
liste.appendChild(zeile(
|
liste.appendChild(zeile(
|
||||||
'Metadaten',
|
'Metadaten',
|
||||||
stand.usingProjectKey ? `Mitgelieferter TMDB-Zugang · ${stand.language}`
|
// Ohne die Sprache: die steht eine Zeile tiefer und gehört dort hin.
|
||||||
: stand.hasApiKey ? `Eigener TMDB-Zugang · ${stand.language}`
|
stand.usingProjectKey ? 'Mitgelieferter TMDB-Zugang'
|
||||||
|
: stand.hasApiKey ? 'Eigener TMDB-Zugang'
|
||||||
: 'Kein Zugang hinterlegt',
|
: 'Kein Zugang hinterlegt',
|
||||||
stand.usingProjectKey
|
stand.usingProjectKey
|
||||||
? 'Ein eigener Zugang löst den mitgelieferten ab.'
|
? 'Ein eigener Zugang löst den mitgelieferten ab.'
|
||||||
|
|||||||
Reference in New Issue
Block a user