defmodule Triple.Types.Validation do
@moduledoc false
alias Triple.Error
# Builds a `Triple.Error.t()` of type `:validation` from a list of
# `{field, message}` pairs produced by `Triple.Types.Validators`. Note
# `status: nil` here — that's how you can tell a *local* validation
# failure (caught before any network call) apart from a `400` the
# server itself returned (which has `status: 400`).
@spec error([{atom(), String.t()}]) :: Error.t()
def error(field_errors) do
errors =
Enum.group_by(
field_errors,
fn {field, _message} -> Atom.to_string(field) end,
fn {_field, message} -> message end
)
%Error{
type: :validation,
message: "Invalid input: " <> format(errors),
status: nil,
errors: errors,
retry_after: nil,
raw_body: nil
}
end
defp format(errors) do
Enum.map_join(errors, "; ", fn {field, messages} ->
"#{field}: #{Enum.join(messages, ", ")}"
end)
end
end