Current section
Files
Jump to
Current section
Files
lib/err.ex
defmodule Err do
@moduledoc """
> Too err is human.
> - Everyone after making a mistake.
Err is a tiny library for dealing with errors. A more detailed explanation is available at [Leveraging Exceptions to handle errors in Elixir](https://leandrocp.com.br/2020/08/leveraging-exceptions-to-handle-errors-in-elixir/).
"""
@doc """
Wraps an `Exception` and its `opts` to return a valid exception.
Any exception can be used, either from Elixir standard library, a third-party library, or defined by you in your application.
## Examples
iex> Err.wrap(KeyError, key: :id)
%KeyError{key: :id}
iex> Err.wrap(MyApp.CustomError, changeset: changeset)
%MyApp.CustomError{changeset: changeset}
Passing only opts will build an `Err.GenericError` exception:
iex> Err.wrap(reason: :boom)
%Err.GenericError{reason: :boom}
"""
def wrap(exception, opts \\ [])
def wrap(exception, opts) when is_atom(exception) do
struct(exception, opts)
end
def wrap(opts, _) do
struct(Err.GenericError, opts)
end
@doc """
Returns a message for a given `exception` or the message defined by `mod`.
## Examples
iex> Err.wrap(ArgumentError) |> Err.message()
"argument error"
iex> Err.wrap(reason: :invalid_value) |> Err.message()
"generic error: :invalid_value"
If you pass a module to the generic error, it will call the function `format_error(reason)`
on that module to format the message:
iex> Err.wrap(mod: MyApp.Auth, reason: :insufficient_permissions) |> Err.message()
"Unable to perform action due to insufficient permissions."
See `Err.GenericError` or README for a complete example.
"""
def message(%_{mod: mod, reason: reason}) when not is_nil(mod) do
mod.format_error(reason)
end
def message(exception) do
Exception.message(exception)
end
end