{"record":{"id":"d0cecfa8096224d6","repo":"binary-husky/gpt_academic","slug":"pdf","errorCode":null,"errorMessage":"PDF生成失败或文件为空","messagePattern":"PDF生成失败或文件为空","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/conversation_doc/word2pdf.py","lineNumber":68,"sourceCode":"                    capture_output=True, text=True\n                )\n\n                if result.returncode != 0:\n                    error_msg = result.stderr or \"未知错误\"\n                    print(f\"LibreOffice转换失败，错误信息: {error_msg}\")\n                    raise RuntimeError(f\"LibreOffice转换失败: {error_msg}\")\n\n                print(f\"LibreOffice转换输出: {result.stdout}\")\n\n                # 如果输出路径与默认生成的不同，则重命名\n                default_pdf = word_path.with_suffix('.pdf')\n                if default_pdf != pdf_path and default_pdf.exists():\n                    os.rename(default_pdf, pdf_path)\n                    print(f\"已将PDF从 {default_pdf} 重命名为 {pdf_path}\")\n\n                # 验证PDF是否成功生成\n                if not pdf_path.exists() or pdf_path.stat().st_size == 0:\n                    raise RuntimeError(\"PDF生成失败或文件为空\")\n\n                print(f\"PDF转换成功，文件大小: {pdf_path.stat().st_size} 字节\")\n            else:\n                # Windows和MacOS使用docx2pdf\n                print(f\"使用docx2pdf转换 {word_path} 到 {pdf_path}\")\n                convert(word_path, pdf_path)\n\n                # 验证PDF是否成功生成\n                if not pdf_path.exists() or pdf_path.stat().st_size == 0:\n                    raise RuntimeError(\"PDF生成失败或文件为空\")\n\n                print(f\"PDF转换成功，文件大小: {pdf_path.stat().st_size} 字节\")\n\n            return str(pdf_path)\n\n        except Exception as e:\n            print(f\"PDF转换异常: {str(e)}\")\n            raise Exception(f\"转换PDF失败: {str(e)}\")","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/conversation_doc/word2pdf.py#L50-L86","documentation":"Raised as RuntimeError on the LibreOffice (Linux) branch after a 'successful' conversion when the expected PDF is missing or zero bytes. LibreOffice exited 0 but either wrote the file somewhere else (e.g. kept a different base name for legacy .doc inputs), silently skipped conversion, or produced an empty file. The code already renames default_pdf to pdf_path when they differ, so this fires only when even the default output is absent/empty.","triggerScenarios":"Input is .doc (not .docx) so with_suffix('.pdf') name assumptions hold but LibreOffice failed silently; outdir different from expected; empty/corrupt document converts to a 0-byte PDF; rename raced or default_pdf never existed and pdf_path was never at the outdir location.","commonSituations":"LibreOffice exit code 0 despite failure (common with headless quirks, e.g. missing javadb filter warnings escalating); wrong --outdir when pdf_path.parent differs from cwd; documents that LibreOffice opens as blank.","solutions":["List the actual outdir contents after conversion to see what filename LibreOffice wrote (it may differ from word_path.stem + '.pdf' for multi-part or temp-named files)","Test the same file with the manual libreoffice CLI command and inspect output/stdout","If the source is .doc, convert to .docx first or match the output name LibreOffice actually produces","Check disk space — a full filesystem yields empty writes with exit 0 in some LO versions","Capture result.stdout in the failure message: LibreOffice reports 'convert ... -> ...' paths there, which pinpoints where the PDF went"],"exampleFix":"// before\nif not pdf_path.exists() or pdf_path.stat().st_size == 0:\n    raise RuntimeError(\"PDF生成失败或文件为空\")\n\n// after\nif not pdf_path.exists() or pdf_path.stat().st_size == 0:\n    produced = list(pdf_path.parent.glob('*.pdf'))\n    raise RuntimeError(\n        f\"PDF生成失败或文件为空: expected={pdf_path}, \"\n        f\"dir_pdf_files={[str(p) for p in produced]}, lo_stdout={result.stdout!r}\")","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\ndef pdf_is_valid(p) -> bool:\n    p = Path(p)\n    return p.exists() and p.stat().st_size > 0 and p.read_bytes()[:5] == b'%PDF-'","typeGuard":null,"tryCatchPattern":"try:\n    pdf = WordToPdfConverter.convert_to_pdf(docx)\nexcept RuntimeError as e:\n    if 'PDF生成失败' in str(e):\n        # LibreOffice can exit 0 silently; look in outdir for what it wrote\n        found = sorted(Path(docx).parent.glob('*.pdf'))\n        if found and found[0].stat().st_size > 0:\n            pdf = str(found[0])  # accept the actually-produced file\n        else:\n            raise","preventionTips":["Verify output with a %PDF- magic-byte check, not just size","Scan the outdir for produced PDFs instead of trusting the predicted filename","Capture LibreOffice stdout in logs — it prints the real output path"],"tags":["libreoffice","pdf-conversion","file-validation","silent-failure"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}