defmodule XRPL.Error do
@moduledoc false
require Logger
defexception [:reason, :details]
@impl true
def exception({reason, %Ecto.Changeset{} = details}) do
%__MODULE__{reason: reason, details: mapper(details)}
end
def exception({reason, details}) do
%__MODULE__{reason: reason, details: inspect(details)}
end
@impl true
def message(%__MODULE__{reason: :validation_error, details: details}) do
message = "XRPL call failed: Invalid params"
Logger.info(message, details: inspect(details))
message
end
def message(%__MODULE__{reason: :request_error, details: %{body: body, url: url}}) do
message = "XRPL call failed: Request error"
Logger.info(message, url: url, body: body)
message
end
defp mapper(%Ecto.Changeset{} = changeset) do
changeset
|> Ecto.Changeset.traverse_errors(fn {msg, opts} ->
Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", _to_string(value))
end)
end)
|> Enum.reduce("", fn {k, v}, acc ->
joined_errors = Enum.join(v, "; ")
"#{acc} #{k}: #{joined_errors}"
end)
|> String.trim_leading()
end
defp _to_string(val) when is_list(val) do
Enum.join(val, ",")
end
defp _to_string(val), do: to_string(val)
end