Image.Error exception (image v0.73.0)

Copy Markdown View Source

The structured exception raised by Image.*!/_arity functions and returned in the error half of every {:ok, _} | {:error, _} tuple in the library.

Every fallible function in Image returns either {:ok, value} or {:error, %Image.Error{}}. Bang variants raise the same struct.

Fields

  • :message — a human-readable description. Always present.

  • :reason — a structured discriminator: an atom (:enoent, :invalid_option, :invalid_color, …), or a binary for free-form libvips errors that don't yet have a structured form. A parameterised error keeps its parameter in :value rather than in :reason, so the reason stays a single atom to match on.

  • :operation — the high-level Image function that failed (e.g. :open, :write, :resize, :draw_rect), or nil if not known.

  • :path — the file system path involved, when applicable.

  • :value — the offending input value, when applicable.

Example

iex> {:error, %Image.Error{reason: :enoent}} = Image.open("/no/such/file.jpg")
iex> :ok
:ok

Pattern matching

Callers should match on :reason rather than scraping :message:

case Image.open(path) do
  {:ok, image} -> ...
  {:error, %Image.Error{reason: :enoent}} -> not_found_handler()
  {:error, %Image.Error{reason: :invalid_option, value: value}} -> ...
  {:error, %Image.Error{} = err} -> raise err
end

A reason that is a binary is a libvips message with no structured form yet. Those are not stable enough to match on, so let them fall through to a catch-all clause.

Constructing

Use the standard defexception callback (exception/1) via raise or by passing structured input:

raise Image.Error, reason: :enoent, path: "/tmp/foo.jpg"

raise Image.Error, "free form message"

Or convert a raw {:error, raw} tuple coming from libvips with Image.Error.wrap/2:

with {:error, raw} <- Vix.Vips.Operation.thumbnail(path, 256) do
  {:error, Image.Error.wrap(raw, operation: :thumbnail)}
end

Summary

Types

t()

A structured Image.Error. The :reason field is the canonical discriminator; :message is always derivable from :reason plus :operation/:path/:value.

Functions

Wraps a raw {:error, _} payload from libvips, the colour library, or another underlying source as an %Image.Error{}.

Types

t()

@type t() :: %Image.Error{
  __exception__: term(),
  message: String.t(),
  operation: atom() | nil,
  path: Path.t() | nil,
  reason: atom() | {atom(), any()} | String.t() | nil,
  value: any() | nil
}

A structured Image.Error. The :reason field is the canonical discriminator; :message is always derivable from :reason plus :operation/:path/:value.

Functions

wrap(raw, context \\ [])

@spec wrap(term(), keyword()) :: t()

Wraps a raw {:error, _} payload from libvips, the colour library, or another underlying source as an %Image.Error{}.

Used at the boundary between Vix and Image to attach high-level context (:operation, :path, :value) before the error propagates to the caller.

Arguments

  • raw is the inner value of the error tuple — typically a string from libvips, an atom from File.*, or another struct that already implements Exception.message/1.

  • context is a keyword list of context fields to attach. The accepted keys are :operation, :path, :value, and :reason (to override the auto-derived reason).

Returns

  • a Image.Error.t/0. This function always returns a struct and never an error tuple, since its purpose is to build the error.

Examples

iex> Image.Error.wrap("operation build: bad seek", operation: :open, path: "/tmp/x.jpg")
%Image.Error{
  reason: "operation build: bad seek",
  operation: :open,
  path: "/tmp/x.jpg",
  message: "open /tmp/x.jpg: operation build: bad seek",
  value: nil
}

iex> Image.Error.wrap(:enoent, path: "/tmp/x.jpg")
%Image.Error{
  reason: :enoent,
  path: "/tmp/x.jpg",
  operation: nil,
  message: "The image file \"/tmp/x.jpg\" was not found or could not be opened",
  value: nil
}