Contexts
View SourceContext Wrapping
The wrap_context/3 function adds context (a label and/or metadata) to any errors which come out of a piece of code. This is especially useful for understanding where a failure came from:
defmodule Users do
alias MyApp.{User, Repo}
def create_user(params) do
with :ok <- check_email_availability(params)
{:ok, changeset} <- User.changeset(%User{}, params)
Repo.insert(changeset)
end
|> Triage.wrap_context("create user", %{email: params[:email]})
end
end
# When an error occurs, you get a `reason` which is a `Triage.WrappedError` exception struct.
{:error, reason} = Users.create_user(%{name: "Alice", email: "alice@example.com"})
# `Exception.message/1` is a standard Elixir function for getting message strings from exceptions
Exception.message(reason)
# => {:error, #Ecto.Changeset<...>}
# [CONTEXT] lib/my_app/users.ex:10: create userYou also might find yourself converting an error into another error in order to make it clear what was happening:
(source)
case AdvertisementService.Stub.advertise(channel, request) do
{:ok, intents} ->
{:ok, intents}
{:error, _} ->
{:error, :failed_to_fetch_intents}
endThis could be a good time to use a context so that the original error is returned along with context label/metadata:
AdvertisementService.Stub.advertise(channel, request)
|> Triage.wrap_context("Fetching advertisement intents", channel_host: channel.host)Make sure to see the Output section for how wrapped errors can be useful without you needing to work with them directly.