fix: "Unexpected token '<'" bei Uploads durch die echte Ursache ersetzen
Alle drei Admin-Upload-Felder riefen response.json() ungeprueft auf. Kam statt JSON eine HTML-Seite zurueck, warf der Parser Unexpected token '<', "<!DOCTYPE "... is not valid JSON und genau dieser Text landete im Formular. Damit war die eigentliche Ursache vollstaendig verdeckt: weder der HTTP-Status noch die Schicht, die abgebrochen hat, waren daraus ablesbar. Der Punkt dabei: die Upload-Route-Handler antworten ausnahmslos mit JSON, auch in jedem Fehlerfall — lokal verifiziert bis hinauf zur Limit-Ueberschreitung (105 MB -> 413 mit JSON-Body). Trifft im Browser trotzdem HTML ein, stammt die Antwort gar nicht aus der Anwendung, sondern aus einer Schicht davor: Reverse-Proxy, CDN oder Gateway, das den Request wegen zu grossem Body abgewiesen oder wegen Zeitueberschreitung beim Transcoding abgebrochen hat. readUploadResponse() in lib/upload-client.ts prueft deshalb zuerst den Content-Type und reicht andernfalls den HTTP-Status nach oben, statt zu parsen. Die Felder zeigen daraus eine Meldung, die den Status nennt und die wahrscheinliche Ursache benennt (413 = vom Proxy abgewiesen, 502/503/504/522/524 = Zeitueberschreitung beim Umrechnen, sonst unerwartet). Ein Verbindungsabbruch, bei dem fetch() selbst wirft, wird getrennt gemeldet. Das behebt nicht die Ursache jenseits der Anwendung — es macht sie zum ersten Mal ablesbar, statt sie hinter einem Parser-Fehler zu verbergen.
This commit is contained in:
1 parent
be5fb32a4a
commit
b11edd7751
8 files changed
+219
-15
No files matched your search
@@ -1139,6 +1139,13 @@ export const en: Dictionary = {
|
||||
remove: "Remove image",
|
||||
removeImageAt: (position) => `Remove image ${position}`,
|
||||
uploadError: "The upload failed.",
|
||||
uploadErrorStatus: (status) =>
|
||||
status === 413
|
||||
? `The file was rejected because it is too large (HTTP 413). It never reached the shop — that limit comes from the reverse proxy or CDN in front of it.`
|
||||
: status === 502 || status === 503 || status === 504 || status === 522 || status === 524
|
||||
? `The server aborted processing (HTTP ${status}). This is almost always a timeout: processing takes longer than the proxy in front of it waits for a response.`
|
||||
: `The server responded unexpectedly (HTTP ${status}) — no usable reply. Please report this number to your technical contact.`,
|
||||
uploadErrorNetwork: "The connection to the server was interrupted during the upload.",
|
||||
},
|
||||
adminVideoField: {
|
||||
none: "No video",
|
||||
@@ -1146,6 +1153,13 @@ export const en: Dictionary = {
|
||||
uploading: "Uploading…",
|
||||
remove: "Remove video",
|
||||
uploadError: "The upload failed.",
|
||||
uploadErrorStatus: (status) =>
|
||||
status === 413
|
||||
? `The video was rejected because it is too large (HTTP 413). It never reached the shop — that limit comes from the reverse proxy or CDN in front of it, not from the shop itself.`
|
||||
: status === 502 || status === 503 || status === 504 || status === 522 || status === 524
|
||||
? `The server aborted processing (HTTP ${status}). For videos this is almost always a timeout: re-encoding for the web takes longer than the proxy in front of it waits for a response. A shorter or smaller video usually gets through.`
|
||||
: `The server responded unexpectedly (HTTP ${status}) — no usable reply. Please report this number to your technical contact.`,
|
||||
uploadErrorNetwork: "The connection to the server was interrupted during the upload.",
|
||||
},
|
||||
adminShell: {
|
||||
navDashboard: "Dashboard",
|
||||
|
||||
Reference in new issue
Block a user