{"record":{"id":"c7ac86f909dd470a","repo":"BigPizzaV3/CodexPlusPlus","slug":"renderer-inject","errorCode":null,"errorMessage":"导出结果不完整","messagePattern":"导出结果不完整","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"assets/inject/renderer-inject.js","lineNumber":6400,"sourceCode":"            httpStatus: 200,\n            responseStatus: fallback.status || \"\",\n          });\n          return fallback;\n        }\n        sendCodexPlusDiagnostic(\"backend_status_bridge_and_http_failed\", {\n          path,\n          errorName: error?.name || \"\",\n          errorMessage: error?.message || String(error),\n        });\n        return fallback;\n      }\n      throw error;\n    }\n  }\n\n  function downloadMarkdownFallback(filename, markdown) {\n    if (!filename || typeof markdown !== \"string\") {\n      throw new Error(\"导出结果不完整\");\n    }\n    const blob = new Blob([markdown], { type: \"text/markdown;charset=utf-8\" });\n    const url = URL.createObjectURL(blob);\n    const anchor = document.createElement(\"a\");\n    anchor.href = url;\n    anchor.download = filename;\n    document.body.appendChild(anchor);\n    anchor.click();\n    anchor.remove();\n    setTimeout(() => URL.revokeObjectURL(url), 1000);\n  }\n\n  async function saveMarkdown(filename, markdown) {\n    if (!filename || typeof markdown !== \"string\") {\n      throw new Error(\"导出结果不完整\");\n    }\n    if (typeof window.showSaveFilePicker !== \"function\") {\n      downloadMarkdownFallback(filename, markdown);","sourceCodeStart":6382,"sourceCodeEnd":6418,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/assets/inject/renderer-inject.js#L6382-L6418","documentation":"downloadMarkdownFallback() is the anchor-download path used when the File System Access API is unavailable. It validates its inputs first: a non-empty filename and a string markdown body are required to build the Blob and trigger the download; otherwise it throws \"导出结果不完整\".","triggerScenarios":"Calling downloadMarkdownFallback(filename, markdown) with filename === \"\"/null/undefined or markdown not a string (null/undefined/object) — typically when the export pipeline produced no content and the caller passed it through unguarded.","commonSituations":"Conversation export ran before the transcript finished loading (empty markdown); a refactor changed saveMarkdown's signature and callers pass an options object; clipboard/stream source returned null on failure.","solutions":["Ensure the markdown is fully generated (await the export/render step) before calling the fallback.","Validate filename and markdown type at the call site and show a user-facing \"nothing to export\" message.","Fix callers that pass (filename, {markdown}) instead of (filename, markdown).","Guard with `if (!markdown) return` upstream instead of letting the fallback throw."],"exampleFix":"// before\ndownloadMarkdownFallback(exportName, maybeMarkdown);\n// after\nif (typeof maybeMarkdown === \"string\" && maybeMarkdown.length && exportName) {\n  downloadMarkdownFallback(exportName, maybeMarkdown);\n} else {\n  showToast(\"导出内容为空，无法下载\");\n}","handlingStrategy":"validation","validationCode":"if (!filename || typeof markdown !== \"string\" || !markdown.trim()) { showToast(\"导出内容为空\"); return; }","typeGuard":"function isExportReady(filename, markdown) { return typeof filename === \"string\" && filename.length > 0 && typeof markdown === \"string\"; }","tryCatchPattern":"try { downloadMarkdownFallback(filename, markdown); } catch (e) { if (e.message === \"导出结果不完整\") showToast(\"没有可导出的内容\"); else throw e; }","preventionTips":["Always await the content-generation step before exporting.","Provide a default filename when template interpolation could be empty.","Validate payload shape at the export button handler, not deep in the fallback."],"tags":["export","validation","markdown"],"backgroundTag":"invalid-argument-value","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}