Errors, safety, and deployment

Copy Markdown View Source

Handle conversion errors

Conversion functions return {:ok, value} or an error map:

case ExAnydoc.to_markdown(path) do
  {:ok, markdown} -> {:ok, markdown}
  {:error, %{code: :encrypted}} -> {:error, "remove the document password"}
  {:error, %{code: :resource_limit}} -> {:error, "document is too complex"}
  {:error, %{code: :io_error} = error} -> {:error, error.message}
  {:error, error} -> {:error, "conversion failed: #{error.message}"}
end

The stable codes are:

CodeMeaning
:unsupportedThe format or requested operation is not supported
:malformedThe document structure is invalid
:encryptedThe document is encrypted
:resource_limitAn upstream parsing safety limit was reached
:missing_partA required part of a compound document is absent
:io_errorReading a file failed

Messages provide diagnostic detail but should not be used as stable identifiers. Invalid Elixir argument types raise instead of returning an error tuple.

Safety

The upstream parser applies fixed limits to archive expansion, nesting, node counts, and retained asset bytes. Still treat native parsing as a resource-heavy operation: validate upload sizes, bound concurrency, and apply application-level timeouts where appropriate. Scanned PDFs require a separate OCR pipeline.

Build and release environments

ExAnydoc currently ships Rust source, not precompiled NIF artifacts. Every environment that runs mix compile for the dependency needs a compatible Rust toolchain and Cargo. In a multi-stage container build, install Rust in the build stage; it does not need to remain in the final runtime image after the release has been assembled.

After changing the Rust or Elixir interface, rebuild and run both suites:

mix test
cargo test --workspace