Structured error raised or returned by PdfElixide operations.
Non-bang functions return {:error, %PdfElixide.Error{}}; bang functions
raise the same struct (it is an exception). Match on :reason to handle
specific failures:
case PdfElixide.Document.open(path) do
{:ok, doc} -> doc
{:error, %PdfElixide.Error{reason: :encrypted}} -> prompt_for_password()
{:error, %PdfElixide.Error{reason: :invalid_pdf}} -> reject()
endReasons
:encrypted— the PDF is encrypted and needs a password first.:wrong_password— the supplied password was rejected. Comes only from the:passwordoption ofopen/2,open!/2,from_binary/2andfrom_binary!/2;PdfElixide.Document.authenticate/2reports a wrong password as{:ok, false}instead.:invalid_pdf— malformed or unparseable PDF data.:invalid_pattern— the search pattern could not be parsed. Comes only fromPdfElixide.Document.search/2and friends underliteral: false.:unsupported— an unsupported PDF version, feature, or filter.:not_found— a referenced object was not found.:out_of_range— the page index is outside the document.:io— an underlying IO error.:panic— the native library panicked on this input, i.e. hit a bug rather than a condition it reports. The handle stays usable, but a panic partway through an operation can leave it holding partially updated state, soclose/1it and reopen if the error recurs.:lock_poisoned— the internal resource lock was poisoned. Should not occur; a native panic is contained and reported as:panicinstead.:closed— the handle was released withclose/1.:other— any error not covered above;messageis preserved verbatim.
:message is a human-readable description. :details is reserved for future
structured payloads and is currently always nil.
Errors versus exceptions
This struct is reserved for PDF and runtime failures. A malformed argument raises instead, even from a non-bang function, because that is a bug in the calling code rather than a condition of the document:
FunctionClauseErrorwhen a guard rejects it — a negative page index, an options argument that is not a keyword list.ArgumentErrorfor everything else, and the message names the offending key. That covers every way an option can be wrong — an unknown key (detect_heading:for:detect_headings), a key given twice, a value the native layer cannot decode, a value out of range ({:min_overlap, 2.0}) — and undecodable values outside an options map, such as a form field value that is not a tagged tuple. A path is opaque bytes and so has almost nothing to reject — only Windows, which cannot name a file in arbitrary bytes, raises here; see the "File paths" section ofPdfElixide.
Build option lists with Keyword.merge/2 rather than ++, since a duplicated
key is rejected instead of resolved to the first occurrence. So nothing about
the caller arrives as a %PdfElixide.Error{}; if you get one, the arguments
were accepted and the document, the filesystem or the handle is what failed.
Predicates ending in ? are the mirror image: they return a bare boolean, so
a failure has nowhere to be reported and this struct is raised instead, from a
function with no ! in its name. PdfElixide.Document.has_structure_tree?/1
and PdfElixide.Document.has_xfa?/1 answer false for a feature that cannot
be read, so only a failure of the handle raises — their strict counterparts
PdfElixide.Document.has_structure_tree/1 and PdfElixide.Document.has_xfa/1
return the error instead. PdfElixide.Document.Page.has_text_layer?/1 raises
for everything, since answering false would invert the meaning callers act
on. PdfElixide.Document.encrypted?/1 asks something that cannot fail, so
only the handle can raise, and closed?/1 never raises at all.
Summary
Types
@type reason() ::
:encrypted
| :wrong_password
| :invalid_pdf
| :invalid_pattern
| :unsupported
| :not_found
| :out_of_range
| :io
| :panic
| :lock_poisoned
| :closed
| :other