{"record":{"id":"5d11960fae62baf8","repo":"binary-husky/gpt_academic","slug":"libreoffice-error-msg","errorCode":null,"errorMessage":"LibreOffice转换失败: {error_msg}","messagePattern":"LibreOffice转换失败: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/conversation_doc/word2pdf.py","lineNumber":56,"sourceCode":"            if platform.system() == 'Linux':\n                # Linux系统需要安装libreoffice\n                which_result = subprocess.run(['which', 'libreoffice'], capture_output=True, text=True)\n                if which_result.returncode != 0:\n                    raise RuntimeError(\"请先安装LibreOffice: sudo apt-get install libreoffice\")\n\n                print(f\"开始转换Word文档: {word_path} 到 PDF\")\n\n                # 使用subprocess代替os.system\n                result = subprocess.run(\n                    ['libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',\n                     str(word_path), '--outdir', str(pdf_path.parent)],\n                    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)","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/conversation_doc/word2pdf.py#L38-L74","documentation":"Raised as RuntimeError when `libreoffice --headless --convert-to pdf:writer_pdf_Export <doc> --outdir <dir>` exits non-zero. The message embeds result.stderr, or '未知错误' when stderr is empty. It means LibreOffice started but the conversion subprocess itself failed.","triggerScenarios":"Corrupt or password-protected .docx; an outdir that does not exist or is not writable; a LibreOffice profile lock from a concurrently running instance; unsupported legacy .doc content; missing fonts causing writer filters to fail; word_path containing shell-hostile characters passed through subprocess list args (usually fine) but pointing to a nonexistent file.","commonSituations":"Running multiple conversions in parallel — LibreOffice headless refuses concurrent runs sharing a user profile; Docker containers missing fonts (fontconfig) or a HOME for the profile; outdir derived from pdf_path.parent that was never created.","solutions":["Reproduce manually with the same args to see the full error: libreoffice --headless --convert-to pdf:writer_pdf_Export file.docx --outdir /tmp/out","If converting concurrently, give each run an isolated profile: add -env:UserInstallation=file:///tmp/lo_profile_<id> to the command","Ensure pdf_path.parent exists (mkdir parents=True) before calling","Install basic fonts in containers: apt-get install -y fontconfig fonts-dejavu","Verify the docx opens in LibreOffice GUI / is not encrypted"],"exampleFix":"// before\nresult = subprocess.run(\n    ['libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',\n     str(word_path), '--outdir', str(pdf_path.parent)],\n    capture_output=True, text=True)\n\n// after\npdf_path.parent.mkdir(parents=True, exist_ok=True)\nresult = subprocess.run(\n    ['-env:UserInstallation=file:///tmp/lo_profile_' + str(os.getpid()),\n     'libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',\n     str(word_path), '--outdir', str(pdf_path.parent)],\n    capture_output=True, text=True, timeout=120)","handlingStrategy":"fallback","validationCode":"import shutil, subprocess, tempfile\n\ndef libreoffice_sane() -> bool:\n    if shutil.which('libreoffice') is None:\n        return False\n    with tempfile.TemporaryDirectory() as d:\n        (Path(d)/'t.docx').write_bytes(minimal_docx_bytes())\n        r = subprocess.run(['libreoffice', '--headless', '--convert-to', 'pdf',\n                            str(Path(d)/'t.docx'), '--outdir', d],\n                           capture_output=True, timeout=60)\n        return r.returncode == 0","typeGuard":null,"tryCatchPattern":"try:\n    pdf = WordToPdfConverter.convert_to_pdf(docx)\nexcept RuntimeError as e:\n    if 'LibreOffice转换失败' in str(e):\n        log.error('LO stderr: %s', e)\n        pdf = convert_with_isolated_profile(docx)  # -env:UserInstallation retry","preventionTips":["Never run concurrent headless conversions sharing one LibreOffice profile; give each run its own -env:UserInstallation","Create the output directory before converting","Install fonts (fontconfig, fonts-dejavu) in minimal containers","Always pass timeout= to the subprocess.run call to avoid indefinite hangs"],"tags":["libreoffice","subprocess","pdf-conversion","concurrency","docker"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}