{"record":{"id":"1b9087bb9c196e04","repo":"Stirling-Tools/Stirling-PDF","slug":"failed-to-export-pdf-error-instanceof-error-e","errorCode":null,"errorMessage":"Failed to export PDF: ${error instanceof Error ? error.message : \"Unknown error\"}","messagePattern":"Failed to export PDF: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/services/pdfExportService.ts","lineNumber":58,"sourceCode":"          : pdfDocument.pages;\n\n      if (pagesToExport.length === 0) {\n        throw new Error(\"No pages to export\");\n      }\n\n      const originalPDFBytes = await pdfDocument.file.arrayBuffer();\n      const blob = await this.createSingleDocument(\n        originalPDFBytes,\n        pagesToExport,\n      );\n      const exportFilename = this.generateFilename(\n        filename || pdfDocument.name,\n      );\n\n      return { blob, filename: exportFilename };\n    } catch (error) {\n      console.error(\"PDF export error:\", error);\n      throw new Error(\n        `Failed to export PDF: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n        { cause: error },\n      );\n    }\n  }\n\n  /**\n   * Export PDF document with applied operations (multi-file source)\n   */\n  async exportPDFMultiFile(\n    pdfDocument: PDFDocument,\n    sourceFiles: Map<string, File>,\n    selectedPageIds: string[] = [],\n    options: ExportOptions = {},\n  ): Promise<{ blob: Blob; filename: string }> {\n    const { selectedOnly = false, filename } = options;\n\n    try {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/services/pdfExportService.ts#L40-L76","documentation":"This is the catch-all wrapper at the end of `exportPDF`. Every error thrown inside the try (the 'No pages to export' precondition, `file.arrayBuffer()` failure, or a `createSingleDocument`/PDFium failure) is re-wrapped as `Failed to export PDF: <inner.message>` with the original attached via `{cause}`. The wrapper itself is not a distinct failure mode — it obscures the real error behind a generic prefix.","triggerScenarios":"Any failure during single-file export: empty page selection (error 24), `pdfDocument.file.arrayBuffer()` rejecting (blob revoked/lost), PDFium `FPDF_CreateNewDocument` returning null (error 29), or an `importPages` failure.","commonSituations":"User clicks Export and something earlier threw; the cause chain holds the real reason but only the prefixed message is shown in the UI.","solutions":["When catching, inspect `error.cause` and branch on known inner errors ('No pages to export' → validation UX; PDFium errors → retry/reload-WASM UX) instead of showing the generic prefix.","Let known precondition errors (validation) propagate unwrapped so callers can distinguish them from engine failures.","Telemetry: log `error.cause?.message` alongside the wrapper so the real cause is captured.","Ensure `pdfDocument.file` is still a live Blob (not revoked) before export."],"exampleFix":"// before\n} catch (error) {\n  console.error(\"PDF export error:\", error);\n  throw new Error(`Failed to export PDF: ${...}`, { cause: error });\n}\n\n// after (preserve known errors verbatim, wrap only unknowns)\n} catch (error) {\n  if (error instanceof Error && error.message === \"No pages to export\") throw error;\n  console.error(\"PDF export error:\", error);\n  throw new Error(`Failed to export PDF: ${...}`, { cause: error });\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the source blob is still live before exporting\nif (!pdfDocument.file || pdfDocument.file.size === 0) {\n  notifyUser(\"The source file is no longer available.\");\n  return;\n}","typeGuard":"function hasCause(e: unknown): e is Error & { cause: unknown } {\n  return e instanceof Error && \"cause\" in e;\n}","tryCatchPattern":"try {\n  return await exportService.exportPDF(doc, ids, opts);\n} catch (e) {\n  const cause = (e as Error & { cause?: Error }).cause;\n  const msg = cause instanceof Error ? cause.message : \"\";\n  if (msg === \"No pages to export\") notifyUser(\"Nothing to export.\");\n  else if (msg.startsWith(\"PDFium\")) notifyUser(\"PDF engine error. Please retry.\");\n  else throw e;\n}","preventionTips":["Always inspect `error.cause` rather than the generic prefix message.","Let validation errors propagate unwrapped so the UI can branch on them.","Verify `pdfDocument.file` is a live, non-empty Blob before export.","Log the inner cause in telemetry to see the real failure distribution."],"tags":["export","error-handling","pdf","wrapper"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}