binary-husky/gpt_academic · error · RuntimeError

LibreOffice转换失败: {error_msg}

Error message

LibreOffice转换失败: {error_msg}

What it means

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.

Source

Thrown at crazy_functions/doc_fns/conversation_doc/word2pdf.py:56

            if platform.system() == 'Linux':
                # Linux系统需要安装libreoffice
                which_result = subprocess.run(['which', 'libreoffice'], capture_output=True, text=True)
                if which_result.returncode != 0:
                    raise RuntimeError("请先安装LibreOffice: sudo apt-get install libreoffice")

                print(f"开始转换Word文档: {word_path} 到 PDF")

                # 使用subprocess代替os.system
                result = subprocess.run(
                    ['libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',
                     str(word_path), '--outdir', str(pdf_path.parent)],
                    capture_output=True, text=True
                )

                if result.returncode != 0:
                    error_msg = result.stderr or "未知错误"
                    print(f"LibreOffice转换失败,错误信息: {error_msg}")
                    raise RuntimeError(f"LibreOffice转换失败: {error_msg}")

                print(f"LibreOffice转换输出: {result.stdout}")

                # 如果输出路径与默认生成的不同,则重命名
                default_pdf = word_path.with_suffix('.pdf')
                if default_pdf != pdf_path and default_pdf.exists():
                    os.rename(default_pdf, pdf_path)
                    print(f"已将PDF从 {default_pdf} 重命名为 {pdf_path}")

                # 验证PDF是否成功生成
                if not pdf_path.exists() or pdf_path.stat().st_size == 0:
                    raise RuntimeError("PDF生成失败或文件为空")

                print(f"PDF转换成功,文件大小: {pdf_path.stat().st_size} 字节")
            else:
                # Windows和MacOS使用docx2pdf
                print(f"使用docx2pdf转换 {word_path} 到 {pdf_path}")
                convert(word_path, pdf_path)

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Reproduce manually with the same args to see the full error: libreoffice --headless --convert-to pdf:writer_pdf_Export file.docx --outdir /tmp/out
  2. If converting concurrently, give each run an isolated profile: add -env:UserInstallation=file:///tmp/lo_profile_<id> to the command
  3. Ensure pdf_path.parent exists (mkdir parents=True) before calling
  4. Install basic fonts in containers: apt-get install -y fontconfig fonts-dejavu
  5. Verify the docx opens in LibreOffice GUI / is not encrypted

Example fix

// before
result = subprocess.run(
    ['libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',
     str(word_path), '--outdir', str(pdf_path.parent)],
    capture_output=True, text=True)

// after
pdf_path.parent.mkdir(parents=True, exist_ok=True)
result = subprocess.run(
    ['-env:UserInstallation=file:///tmp/lo_profile_' + str(os.getpid()),
     'libreoffice', '--headless', '--convert-to', 'pdf:writer_pdf_Export',
     str(word_path), '--outdir', str(pdf_path.parent)],
    capture_output=True, text=True, timeout=120)
Defensive patterns

Strategy: fallback

Validate before calling

import shutil, subprocess, tempfile

def libreoffice_sane() -> bool:
    if shutil.which('libreoffice') is None:
        return False
    with tempfile.TemporaryDirectory() as d:
        (Path(d)/'t.docx').write_bytes(minimal_docx_bytes())
        r = subprocess.run(['libreoffice', '--headless', '--convert-to', 'pdf',
                            str(Path(d)/'t.docx'), '--outdir', d],
                           capture_output=True, timeout=60)
        return r.returncode == 0

Try / catch

try:
    pdf = WordToPdfConverter.convert_to_pdf(docx)
except RuntimeError as e:
    if 'LibreOffice转换失败' in str(e):
        log.error('LO stderr: %s', e)
        pdf = convert_with_isolated_profile(docx)  # -env:UserInstallation retry

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/5d11960fae62baf8. Report an issue: GitHub.