Exceptional v2.1.3 Exceptional.Normalize View Source

Normalize values to a consistent exception struct or plain value. In some ways this can be seen as the opposite of tagged_tuple/ok.

Link to this section Summary

Functions

Normalizes values into exceptions or plain values (no {:error, _} tuples). Some error types may not be detected; you may pass a custom converter. See more below

Link to this section Functions

Link to this function

normalize(error_or_value, conversion_fun \\ fn x -> x end) View Source
normalize(any(), (... -> any())) :: any()

Normalizes values into exceptions or plain values (no {:error, _} tuples). Some error types may not be detected; you may pass a custom converter. See more below.

Normal values will simply pass through:

iex> normalize(42)
42

Struct exceptions will also pass straight through:

iex> normalize(%Enum.OutOfBoundsError{message: "out of bounds error"})
%Enum.OutOfBoundsError{message: "out of bounds error"}

This covers the most common tuple error cases (see examples below), but is by no means exhaustive.

iex> normalize(:error)
%ErlangError{original: nil}

iex> normalize(:error)
%ErlangError{original: nil}

iex> normalize({:error, "boom"})
%ErlangError{original: "boom"}

iex> normalize({:error, {1, 2, 3}})
%ErlangError{original: {1, 2, 3}}

iex> normalize({:error, "boom with stacktrace", ["trace"]})
%ErlangError{original: "boom with stacktrace"}

Some errors tuples cannot be detected. Those cases will be returned as plain values.

iex> normalize({:good, "tuple", ["value"]})
{:good, "tuple", ["value"]}

You may optionally pass a converting function as a second argument. This allows you to construct a variant of normalize that accounts for some custom error message(s).

iex> {:oh_no, {"something bad happened", %{bad: :thing}}}
...> |> normalize(fn
...>   {:oh_no, {message, _}} -> %File.Error{reason: message}
...>   {:bang, message}       -> %File.CopyError{reason: message}
...>   otherwise              -> otherwise
...> end)
%File.Error{reason: "something bad happened"}

iex> {:oh_yes, {1, 2, 3}}
...> |> normalize(fn
...>   {:oh_no, {message, _}} -> %File.Error{reason: message}
...>   {:bang, message}       -> %File.CopyError{reason: message}
...>   otherwise              -> otherwise
...> end)
{:oh_yes, {1, 2, 3}}