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);
|
||||
}
|
||||
|
||||
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 ---------- */
|
||||
|
||||
@@ -872,8 +872,9 @@ function serverbereich(geaendert: () => void): HTMLElement {
|
||||
|
||||
liste.appendChild(zeile(
|
||||
'Metadaten',
|
||||
stand.usingProjectKey ? `Mitgelieferter TMDB-Zugang · ${stand.language}`
|
||||
: stand.hasApiKey ? `Eigener TMDB-Zugang · ${stand.language}`
|
||||
// Ohne die Sprache: die steht eine Zeile tiefer und gehört dort hin.
|
||||
stand.usingProjectKey ? 'Mitgelieferter TMDB-Zugang'
|
||||
: stand.hasApiKey ? 'Eigener TMDB-Zugang'
|
||||
: 'Kein Zugang hinterlegt',
|
||||
stand.usingProjectKey
|
||||
? 'Ein eigener Zugang löst den mitgelieferten ab.'
|
||||
|
||||
Reference in New Issue
Block a user