{"record":{"id":"d60f8fe6d6757d83","repo":"gildas-lormeau/SingleFile","slug":"error-message-restformapi","errorCode":null,"errorMessage":"error.message + \" (RestFormApi)\"","messagePattern":"error\\.message \\+ \" \\(RestFormApi\\)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/downloads.js","lineNumber":657,"sourceCode":"\tdocument.removeEventListener(command, listener);\n\n\tfunction listener(event) {\n\t\tevent.clipboardData.setData(pageData.mimeType, pageData.content);\n\t\tevent.clipboardData.setData(\"text/plain\", pageData.content);\n\t\tevent.preventDefault();\n\t}\n}\n\nasync function saveToRestFormApi(taskId, filename, content, url, token, restApiUrl, fileFieldName, urlFieldName) {\n\ttry {\n\t\tconst taskInfo = business.getTaskInfo(taskId);\n\t\tif (!taskInfo || !taskInfo.cancelled) {\n\t\t\tconst client = new RestFormApi(token, restApiUrl, fileFieldName, urlFieldName);\n\t\t\tbusiness.setCancelCallback(taskId, () => client.abort());\n\t\t\treturn await client.upload(filename, content, url);\n\t\t}\n\t} catch (error) {\n\t\tthrow new Error(error.message + \" (RestFormApi)\", { cause: error });\n\t}\n}\n\nasync function downloadPageForeground(taskId, filename, content, mimeType, tabId, { foregroundSave, sharePage } = {}) {\n\tconst serializer = yabson.getSerializer({\n\t\tfilename,\n\t\ttaskId,\n\t\tforegroundSave,\n\t\tsharePage,\n\t\tcontent: await content.arrayBuffer(),\n\t\tmimeType\n\t});\n\tfor await (const data of serializer) {\n\t\tawait browser.tabs.sendMessage(tabId, {\n\t\t\tmethod: \"content.download\",\n\t\t\tdata: Array.from(data)\n\t\t});\n\t}","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/downloads.js#L639-L675","documentation":"saveToRestFormApi wraps any error from the RestFormApi client upload (new RestFormApi(token, restApiUrl, fileFieldName, urlFieldName).upload(filename, content, url)) and rethrows with an \" (RestFormApi)\" suffix plus the original error as cause. It identifies the REST form API destination as the failure point.","triggerScenarios":"Any rejection inside RestFormApi.upload called from downloadContent/downloadCompressedContent: server unreachable, 401/403 auth, wrong field names, malformed endpoint, or abort.","commonSituations":"REST API URL wrong or not HTTPS; token missing/expired; server expects multipart fields with different names than fileFieldName/urlFieldName configured; CORS or reverse proxy blocking the POST.","solutions":["Check error.cause for the HTTP status and verify restApiUrl is correct","Confirm fileFieldName and urlFieldName match the server's expected multipart field names","Validate/refresh the token","Test the endpoint manually with a curl multipart POST to compare behavior"],"exampleFix":"// before\nnew RestFormApi(token, 'https://api.example.com/save', 'file', 'url');\n// server expects field 'upload'\n// after\nnew RestFormApi(token, 'https://api.example.com/save', 'upload', 'url');","handlingStrategy":"validation","validationCode":"try { new URL(restApiUrl); } catch { throw new Error('Invalid RestFormApi URL'); }\nif (!token) throw new Error('Missing RestFormApi token');\nif (!fileFieldName || !urlFieldName) throw new Error('Missing multipart field names');","typeGuard":"function hasRestFormConfig(o) {\n  try { return !!new URL(o.restApiUrl) && !!o.token && !!o.fileFieldName && !!o.urlFieldName; }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  await saveToRestFormApi(taskId, filename, content, restOpts);\n} catch (error) {\n  if (error.message.endsWith('(RestFormApi)')) {\n    console.error('REST save failed:', error.cause);\n    // inspect status in cause; fix field names or token\n  } else { throw error; }\n}","preventionTips":["Confirm multipart field names against the server's API docs","Validate the endpoint with a curl multipart POST during setup","Keep the token fresh and scoped to the upload endpoint","Log error.cause to capture the raw HTTP status"],"tags":["rest-api","upload","error-wrapping","network"],"backgroundTag":"rest-api-upload-failed","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}