fix: properly surface errors from embedded attributes

This commit is contained in:
Zach Daniel 2023-01-22 10:40:38 -05:00
parent 0a76ee77da
commit 71dcb17e8b

View file

@ -3337,32 +3337,57 @@ defmodule Ash.Changeset do
end end
Enum.reduce(messages, changeset, fn message, changeset -> Enum.reduce(messages, changeset, fn message, changeset ->
opts = error_to_exception_opts(message, attribute) if Exception.exception?(message) do
exception =
case type do
:attribute -> InvalidAttribute
:argument -> InvalidArgument
end
Enum.reduce(opts, changeset, fn opts, changeset ->
error = error =
exception.exception( message
value: value, |> Ash.Error.to_ash_error()
field: Keyword.get(opts, :field),
message: Keyword.get(opts, :message),
vars: opts
)
error = errors =
if opts[:path] do case error do
Ash.Error.set_path(error, opts[:path]) %class{errors: errors}
else when class in [
error Ash.Error.Invalid,
Ash.Error.Unknown,
Ash.Error.Forbidden,
Ash.Error.Framework
] ->
errors
error ->
[error]
end end
add_error(changeset, error) Enum.reduce(errors, changeset, fn error, changeset ->
end) add_error(changeset, Ash.Error.set_path(error, attribute.name))
end)
else
opts = error_to_exception_opts(message, attribute)
exception =
case type do
:attribute -> InvalidAttribute
:argument -> InvalidArgument
end
Enum.reduce(opts, changeset, fn opts, changeset ->
error =
exception.exception(
value: value,
field: Keyword.get(opts, :field),
message: Keyword.get(opts, :message),
vars: opts
)
error =
if opts[:path] do
Ash.Error.set_path(error, opts[:path])
else
error
end
add_error(changeset, error)
end)
end
end) end)
end end
@ -3404,6 +3429,11 @@ defmodule Ash.Changeset do
message when is_binary(message) -> message when is_binary(message) ->
[[field: attribute.name, message: message]] [[field: attribute.name, message: message]]
value when is_exception(value) ->
value
|> Ash.Error.to_ash_error()
|> Map.put(:field, attribute.name)
_ -> _ ->
[[field: attribute.name]] [[field: attribute.name]]
end end