Diagnostics
View SourceNative Elixir PDF Utilities returns recoverable public API failures as
{:error, {reason, diagnostic}} when the library can explain why an operation
cannot continue.
The reason atom is intended for programmatic branching. The diagnostic map is
intended for developer debugging, logs, and user-facing support messages.
Diagnostic Fields
Diagnostic maps always include:
:stage- the pipeline or utility stage that failed:reason- the machine-readable reason atom:message- a human-readable explanation
Diagnostic maps may also include:
:operation- the public API or file operation being performed:module- the public module returning the error:source- a path, source snippet, or caller-provided input label:lineand:column- source location details when parser input can be located
Example
case NativeElixirPdfUtilities.Text.extract_file(path) do
{:ok, text} ->
text
{:error, {_reason, diagnostic}} ->
Logger.warning(diagnostic.message)
endExample Diagnostic
{:error,
{:invalid_path,
%{
stage: :file,
reason: :invalid_path,
message: "path must be a string",
operation: :extract_file,
module: NativeElixirPdfUtilities.Text
}}}Contributor Guidance
Use NativeElixirPdfUtilities.Diagnostics for new public API failures instead
of inventing per-module error shapes.
Changes to the shared diagnostics API, including its tuple shape, fields, and
types, are permitted only when there is no other way to return correct debug
information to the developer using the existing contract. Prefer expressing
additional detail through the existing :message and :source fields.
Do not raise for ordinary caller/input failures such as invalid paths, missing files, unsupported documents, unsupported HTML/CSS, or empty extraction results. Prefer diagnostic error tuples and add focused tests that assert the important fields.
Malformed PDF Input
The shared reader used by Merge.merge/1 and Text.extract/2 validates PDF
headers, final xref pointers, object boundaries, stream lengths, page trees,
and indirect references before continuing. Malformed input returns an
:invalid_pdf_input diagnostic rather than producing partial output or
raising. Encrypted PDFs return :encrypted_pdf; unsupported stream features
return :unsupported_pdf_feature; custom fonts without a reliable Unicode
mapping return :unsupported_text_encoding; image-only PDFs return
:no_extractable_text from the reconstructed string API.
The tokenizer represents malformed literal and hexadecimal strings as
{:error, reason} tokens. This is primarily useful to callers using
NativeElixirPdfUtilities.Tokenizer directly; merge and text extraction convert
such tokenization failures into their public diagnostic error shape.
To protect extraction from resource exhaustion, the shared reader applies input,
decoded-stream, ratio, object/page, CMap, and recursion limits. A limit failure
returns :resource_limit_exceeded; it is never converted to a partial result.