Skip to content

Commit

Permalink
Improve Ecto.InvalidChangesetError message for embeds (#1796)
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtekmach authored and josevalim committed Dec 11, 2016
1 parent 7a21691 commit 4877374
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 7 deletions.
40 changes: 34 additions & 6 deletions lib/ecto/exceptions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,50 @@ defmodule Ecto.InvalidChangesetError do
defexception [:action, :changeset]

def message(%{action: action, changeset: changeset}) do
changes = extract_changes(changeset)
errors = Ecto.Changeset.traverse_errors(changeset, & &1)

"""
could not perform #{action} because changeset is invalid.
* Changeset changes
Applied changes
#{pretty changes}
#{inspect changeset.changes}
Params
* Changeset params
#{pretty changeset.params}
#{inspect changeset.params}
Errors
* Changeset errors
#{pretty errors}
#{inspect changeset.errors}
Changeset
#{pretty changeset}
"""
end

defp pretty(term) do
inspect(term, pretty: true)
|> String.split("\n")
|> Enum.map_join("\n", &" " <> &1)
end

defp extract_changes(%Ecto.Changeset{changes: changes}) do
Enum.reduce(changes, %{}, fn({key, value}, acc) ->
case value do
%Ecto.Changeset{action: :delete} -> acc
_ -> Map.put(acc, key, extract_changes(value))
end
end)
end
defp extract_changes([%Ecto.Changeset{action: :delete} | tail]),
do: extract_changes(tail)
defp extract_changes([%Ecto.Changeset{} = changeset | tail]),
do: [extract_changes(changeset) | extract_changes(tail)]
defp extract_changes(other),
do: other
end

defmodule Ecto.CastError do
Expand Down
2 changes: 1 addition & 1 deletion test/ecto/repo_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ defmodule Ecto.RepoTest do
end

test "insert!, update!, insert_or_update! and delete! fail on invalid changeset" do
invalid = %Ecto.Changeset{valid?: false, data: %MySchema{}}
invalid = %Ecto.Changeset{valid?: false, data: %MySchema{}, types: %{}}

assert_raise Ecto.InvalidChangesetError,
~r"could not perform insert because changeset is invalid", fn ->
Expand Down

0 comments on commit 4877374

Please sign in to comment.