{"record":{"id":"d3c66d9b884dcc79","repo":"gildas-lormeau/SingleFile","slug":"response-error","errorCode":null,"errorMessage":"response.error","messagePattern":"response\\.error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bg/downloads.js","lineNumber":343,"sourceCode":"\t\t\t\t\ttabIndex: tab.index + 1,\n\t\t\t\t\tfilename: message.filename,\n\t\t\t\t\tcontent: Array.from(new Uint8Array(await blob.arrayBuffer())),\n\t\t\t\t\tcompressContent: message.compressContent,\n\t\t\t\t\tselfExtractingArchive: message.selfExtractingArchive,\n\t\t\t\t\tdisableCompression: message.disableCompression,\n\t\t\t\t\textractDataFromPage: message.extractDataFromPage,\n\t\t\t\t\tinsertTextBody: message.insertTextBody,\n\t\t\t\t\tinsertMetaCSP: message.insertMetaCSP,\n\t\t\t\t\tembeddedImage: message.embeddedImage,\n\t\t\t\t\turl: message.originalUrl\n\t\t\t\t});\n\t\t\t} else if (message.foregroundSave || !message.backgroundSave || message.sharePage) {\n\t\t\t\tconst response = await downloadPageForeground(message.taskId, message.filename, blob, pageData.mimeType, tabId, {\n\t\t\t\t\tforegroundSave: true,\n\t\t\t\t\tsharePage: message.sharePage\n\t\t\t\t});\n\t\t\t\tif (response.error) {\n\t\t\t\t\tthrow new Error(response.error);\n\t\t\t\t}\n\t\t\t} else if (message.saveWithWebDAV) {\n\t\t\t\tresponse = await saveWithWebDAV(message.taskId, encodeSharpCharacter(message.filename), blob, message.webDAVURL, message.webDAVUser, message.webDAVPassword, { filenameConflictAction: message.filenameConflictAction, prompt });\n\t\t\t} else if (message.saveWithMCP) {\n\t\t\t\tresponse = await saveWithMCP(message.taskId, encodeSharpCharacter(message.filename), blob, message.mcpServerUrl, message.mcpAuthToken, { filenameConflictAction: message.filenameConflictAction, prompt });\n\t\t\t} else if (message.saveToGDrive) {\n\t\t\t\tawait saveToGDrive(message.taskId, encodeSharpCharacter(message.filename), blob, {\n\t\t\t\t\tforceWebAuthFlow: message.forceWebAuthFlow\n\t\t\t\t}, {\n\t\t\t\t\tonProgress: (offset, size) => ui.onUploadProgress(tabId, offset, size),\n\t\t\t\t\tfilenameConflictAction: message.filenameConflictAction,\n\t\t\t\t\tprompt\n\t\t\t\t});\n\t\t\t} else if (message.saveToDropbox) {\n\t\t\t\tawait saveToDropbox(message.taskId, encodeSharpCharacter(message.filename), blob, {\n\t\t\t\t\tonProgress: (offset, size) => ui.onUploadProgress(tabId, offset, size),\n\t\t\t\t\tfilenameConflictAction: message.filenameConflictAction,\n\t\t\t\t\tprompt","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/gildas-lormeau/SingleFile/blob/517fb7c5cf2096d89933b747e862d8ecf616a9f9/src/core/bg/downloads.js#L325-L361","documentation":"In downloadCompressedContent, when the page must be saved in the foreground (foregroundSave, or non-background save / sharePage), downloadPageForeground's response is checked and any truthy response.error is re-thrown as Error(response.error). This surfaces whatever error the foreground save dialog/pipeline reported (e.g. save cancelled, download interrupted) as the thrown message.","triggerScenarios":"Calling downloadTabPage with foregroundSave true (or backgroundSave false / sharePage true) and downloadPageForeground returns { error: '...' } — e.g. the browser download was cancelled, blocked, or failed.","commonSituations":"User cancels the browser 'Save As' dialog; download filename conflicts resolved as failure; share-sheet errors on mobile; disk/permission failures in the foreground save path.","solutions":["Catch and inspect err.message — it is the raw foreground-save error string; handle known values (e.g. cancellations) distinctly.","Retry with backgroundSave instead of foregroundSave to bypass the interactive path.","Check the response.error string for 'cancelled' vs real failures to decide whether to surface to the user."],"exampleFix":"// before\nawait downloadTabPage(tabId, { ...message, foregroundSave: true });\n// after\ntry { await downloadTabPage(tabId, { ...message, foregroundSave: true }); }\ncatch (err) {\n  if (/cancel/i.test(err.message)) return; // user cancelled Save As\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await downloadTabPage(tabId, message); } catch (e) { if (/cancel/i.test(e.message)) return; throw e; }","preventionTips":["Inspect err.message — it carries the raw foreground-save error string","Offer a backgroundSave fallback path","Distinguish user cancellations from real download failures before reporting"],"tags":["download","foreground-save","propagated-error"],"backgroundTag":"foreground-download-failed","analyzedSha":"517fb7c5cf2096d89933b747e862d8ecf616a9f9","analyzedAt":"2026-09-01T10:05:25.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}