fireproofsocks
Collecting and formatting changeset errors?
I’m using changesets to validate various API submissions and I’m wondering if someone has come up with an easy way to format the errors? It’s a lot of busy work to traverse the changeset errors and assemble a meaningful error message, so I thought I’d ask the forum people to see if someone had already solved that particular problem (yes, I’m fishing). Thank you!
Most Liked Responses
fireproofsocks
Here’s what I have… useful for formatting the changeset errors into a string for logging etc.
def changeset_error_to_string(changeset) do
Ecto.Changeset.traverse_errors(changeset, 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}\n"
end)
end
It’ll return a string like
"password: Not enough special characters (only 0 instead of at least 1); Not enough numbers characters (only 0 instead of at least 1); Not enough upper_case characters (only 0 instead of at least 1)\n"
vetikent
I had to add a case for when the traversed error value came as an error:
defp _to_string(val) when is_list(val) do
Enum.join(val, ",")
end
defp _to_string(val), do: to_string(val)
Full implementation:
defmodule Yourapp.Ecto.Errors do
def mapper(%Ecto.Changeset{} = changeset) do
IO.inspect(changeset)
Ecto.Changeset.traverse_errors(changeset, 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)
end
def mapper(changeset), do: changeset
defp _to_string(val) when is_list(val) do
Enum.join(val, ",")
end
defp _to_string(val), do: to_string(val)
end
mikemccall
traverse_errors/2 might help out








