Description
When exiftool_path is set but points to a non-existent binary, exiftool_metadata() crashes with an unhandled FileNotFoundError instead of returning an empty metadata dict or raising a clear error.
The subprocess.run() call on line 22 (and 41) raises FileNotFoundError when the binary is not found, but the except clause only catches CalledProcessError and ValueError.
Root Cause
packages/markitdown/src/markitdown/converters/_exiftool.py, lines 21-27:
try:
version_output = subprocess.run(
[exiftool_path, "-ver"],
capture_output=True, text=True, check=True,
).stdout.strip()
...
except (subprocess.CalledProcessError, ValueError) as e:
raise RuntimeError("Failed to verify ExifTool version.") from e
FileNotFoundError (when the binary doesn't exist) is a subclass of OSError, not CalledProcessError or ValueError, so it propagates uncaught.
Expected Behavior
If exiftool_path points to a non-existent file, exiftool_metadata() should return an empty dict (graceful degradation) rather than crashing the entire conversion.
Proposed Fix
Add OSError (parent of FileNotFoundError) to the except clause.
Description
When
exiftool_pathis set but points to a non-existent binary,exiftool_metadata()crashes with an unhandledFileNotFoundErrorinstead of returning an empty metadata dict or raising a clear error.The
subprocess.run()call on line 22 (and 41) raisesFileNotFoundErrorwhen the binary is not found, but theexceptclause only catchesCalledProcessErrorandValueError.Root Cause
packages/markitdown/src/markitdown/converters/_exiftool.py, lines 21-27:FileNotFoundError(when the binary doesn't exist) is a subclass ofOSError, notCalledProcessErrororValueError, so it propagates uncaught.Expected Behavior
If
exiftool_pathpoints to a non-existent file,exiftool_metadata()should return an empty dict (graceful degradation) rather than crashing the entire conversion.Proposed Fix
Add
OSError(parent ofFileNotFoundError) to the except clause.