{"record":{"id":"0ff6e040703f52c2","repo":"gildas-lormeau/SingleFile","slug":"await-response-text","errorCode":null,"errorMessage":"await response.text()","messagePattern":"await response\\.text\\(\\)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/lib/rest-form-api/index.js","lineNumber":65,"sourceCode":"\t\tthis.controller = new AbortController();\n\t\tconst blob = content instanceof Blob ? content : new Blob([content], { type: \"text/html\" });\n\t\tlet formData = new FormData();\n\t\tif (this.fileFieldName) {\n\t\t\tformData.append(this.fileFieldName, blob, filename);\n\t\t}\n\t\tif (this.urlFieldName) {\n\t\t\tformData.append(this.urlFieldName, url);\n\t\t}\n\t\tconst response = await fetch(this.restApiUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: formData,\n\t\t\theaders: this.headers,\n\t\t\tsignal: this.controller.signal\n\t\t});\n\t\tif ([200, 201, 202].includes(response.status)) {\n\t\t\treturn response.json();\n\t\t} else {\n\t\t\tthrow new Error(await response.text());\n\t\t}\n\t}\n\n\tabort() {\n\t\tif (this.controller) {\n\t\t\tthis.controller.abort();\n\t\t}\n\t}\n}\n","sourceCodeStart":47,"sourceCodeEnd":75,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/lib/rest-form-api/index.js#L47-L75","documentation":"upload() in the REST form API treats only HTTP 200/201/202 as success; for any other status it throws an Error whose message is the raw response body text (await response.text()). The message you see is literally whatever error payload the server returned, so the server's response text is the diagnostic.","triggerScenarios":"Uploading a file when the server responds 400 (invalid form fields/boundary), 401/403 (bad credentials), 404 (wrong endpoint URL), 413 (file too large), or 5xx — anything outside [200,201,202].","commonSituations":"Expired or missing auth token; API endpoint path changed or is environment-specific; upload exceeding server max body size; malformed multipart form construction; server temporarily down.","solutions":["Log the full thrown message (response text) — it contains the server's error description; fix the root cause it names","Check the endpoint URL, HTTP method and multipart field names against the API docs","Verify auth headers/token validity and the request's Content-Type/boundary","Add handling for rate limits (429) and large files (413), with retry/backoff for 5xx"],"exampleFix":"// before\n} else {\n  throw new Error(await response.text());\n}\n// after\n} else {\n  const body = await response.text();\n  const err = new Error(`Upload failed (${response.status}): ${body}`);\n  err.status = response.status;\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":"if (!file || file.size > MAX_UPLOAD_BYTES) throw new Error(`File too large: ${file && file.size} bytes`);\nif (!this.headers.Authorization) throw new Error(\"Missing auth token for form API upload\");","typeGuard":"function isUploadSuccess(res) { return [200, 201, 202].includes(res && res.status); }","tryCatchPattern":"try {\n  await api.upload(file);\n} catch (e) {\n  const status = extractStatus(e); // parse from server text or track separately\n  if (status === 429 || status >= 500) await retryWithBackoff(() => api.upload(file));\n  else if (status === 401) await reauthenticate();\n  else throw e;\n}","preventionTips":["Include response.status in thrown errors for programmatic handling","Check token validity/expiry before uploads","Enforce client-side file size limits matching server limits","Verify endpoint URL per environment (staging vs prod)"],"tags":["http","upload","rest-api"],"backgroundTag":"http-error-response","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}