Skip to content

ODA File Converter CLI exits 0 on failed conversions (error goes to <stem>.dxf.err); missing args open a GUI and hang

Batch-converting DWG to DXF from Python with ODA File Converter 27.9 on macOS: subprocess.run([oda, in_dir, out_dir, 'ACAD2018', 'DXF', '0', '0', 'drawing.dwg'], check=True). A truncated DWG produced no DXF, yet the process exited 0 with nothing on stdout or stderr, so the script reported success and failed later when it opened the missing file. Checking returncode and stderr told me nothing. An earlier version of the wrapper passed fewer positional arguments (and the input file instead of a folder); the subprocess then never returned, because a Qt window had opened on the desktop. The help text lists the arguments but says nothing about how errors are reported.

1 solution
ranked by outcome — not votes
Accepted

ODA File Converter reports per-file failures by writing <output_dir>/<stem>.dxf.err (or .dwg.err), not through the exit status. For a 13-byte truncated DWG the file contains:

OdError thrown during readFile of drawing "/path/in/t.dwg" :
  Unexpected end of file

Exit status is 0 either way (verified on 27.9.0.0, macOS arm64).

It runs headless only when all seven positional arguments are given: input folder, output folder, output version (ACAD2018...), output type (DXF/DWG), recurse (0/1), audit (0/1), and an input filter. The filter can be an exact file name, which is how you convert one file out of a folder. With fewer arguments it starts the GUI and blocks.

Wrapper that detects failure:

import subprocess
from pathlib import Path

def oda_to_dxf(oda: str, dwg: Path, out: Path) -> Path:
    dxf, err = out / f"{dwg.stem}.dxf", out / f"{dwg.stem}.dxf.err"
    dxf.unlink(missing_ok=True); err.unlink(missing_ok=True)  # stale outputs would mask a failure
    result = subprocess.run([oda, str(dwg.parent), str(out), "ACAD2018", "DXF", "0", "0", dwg.name],
                            stdin=subprocess.DEVNULL, capture_output=True, timeout=600)
    if err.exists():
        raise RuntimeError(" ".join(err.read_text(errors="replace").split()))
    if not dxf.exists():
        raise RuntimeError(f"no output (exit {result.returncode})")
    return dxf

Notes:

  • macOS binary: /Applications/ODAFileConverter.app/Contents/MacOS/ODAFileConverter; a symlink on PATH works.
  • The audit flag changes content: on one R2018 drawing, audit=1 produced 2 fewer SPLINE entities (51,619 vs 51,621) than audit=0. Pick one and keep it fixed if you compare runs.
  • [Untested] It is a Qt app; over ssh without a logged-in GUI session it may fail to start. The no-output branch above catches that.