Packages

Initially build to reduce the author's pain point when using erlang tuple style error handling where it has no information of who create the error tuple.

Current section

Files

Jump to
errx lib errx.ex
Raw

lib/errx.ex

defmodule Errx do
@type t :: %Errx{}
defstruct [:file, :func, :reason, :parent]
@spec wrap(any) :: Errx.t()
def wrap(error) do
{mod, fname, farity, [file: file, line: line]} =
Process.info(self(), :current_stacktrace) |> elem(1) |> Enum.fetch!(2)
func = "#{mod}.#{fname}/#{farity}"
file = "#{file}:#{line}"
case error do
%Errx{} ->
error
{:error, reason} ->
%Errx{func: func, file: file, reason: reason}
reason ->
%Errx{func: func, file: file, reason: reason}
end
end
defmacro wrap(parent_error, child_error) do
quote do
%Errx{Errx.wrap(unquote(child_error)) | parent: Errx.wrap(unquote(parent_error))}
end
end
defmacro match(reason) do
quote do
%Errx{reason: unquote(reason)}
end
end
@spec match(any, any) :: boolean
def match(%Errx{reason: err1}, {:error, err2}) do
err1 == err2
end
def match({:error, err1}, %Errx{reason: err2}) do
err1 == err2
end
def match(err1, %Errx{reason: err2}) do
err1 == err2
end
def match(%Errx{reason: err1}, err2) do
err1 == err2
end
end