When Conversion Must Refuse: Recovery, Limits, and Trust
A readable Markdown string is not automatically a trustworthy conversion. This chapter examines how anydoc decides whether damaged or unusually shaped input can still produce a complete result, when it should skip a recoverable detail, and when it must stop with a typed error. The practical judgment is simple but demanding: downstream code should be able to treat success as meaningful without mistaking partial survival for complete extraction.
An error means the complete result is unavailable
anydoc defines a conversion error around the result, not around the mere presence of a defect. Its typed error family covers unknown or unsupported input, scanned PDF pages that need OCR, structurally unusable documents, encryption, fixed resource limits, missing required parts, and file-read failures. These cases differ in cause, but they share an important consequence: the library cannot return a complete useful Markdown document under its local contract.
That contract is stricter than “extract whatever text happens to be easy.” A damaged document may contain readable paragraphs alongside a missing primary part. A PDF may have searchable text on most pages and image-only content on a few. An encrypted package may reveal a container signature without revealing the document inside. Returning the surviving text as if it were the whole document would move the uncertainty downstream, where a search index, summarizer, or analyst might never know what was omitted.
The distinction between a typed failure and a successful result therefore protects meaning. An unsupported outcome says that anydoc does not have a usable path for the input. encrypted says that access is blocked rather than that the document is empty. needsOcr identifies a capability gap and can include the affected PDF pages. malformed or missingPart points toward structural damage. A resource-limit error says that processing was stopped at a safety boundary. The caller can record these categories, route them differently, or retry with a different capability without reducing them all to “conversion failed.”
This is also why anydoc’s public bindings preserve stable error identities. Node exposes a machine-readable error code, and Python maps the Rust variants to typed exceptions with details such as OCR pages, the missing package part, or the limit crossed. A batch pipeline can use those distinctions to continue past an encrypted file while escalating a repeated resource-limit event, or to send only OCR-required documents through a hosted path. The details are operationally useful because they describe what the system knows about the failure rather than merely reporting that a string was not returned.
The categories also imply different retry behavior. Repeating an unsupported or encrypted conversion with the same local call is unlikely to change the outcome. A malformed file may need inspection or a corrected export. A needsOcr result can move to a capability that the local Rust path intentionally does not provide. A missing required part may justify quarantining the source rather than publishing a partial record.