fix: exception on invalid query arguments

This commit is contained in:
Zach Daniel 2021-03-21 14:19:45 -04:00
parent ac72c623d9
commit 4e8bd5bfbc
2 changed files with 66 additions and 11 deletions

View file

@ -726,12 +726,13 @@ defmodule Ash.Query do
query = to_query(query)
if query.action do
with {:arg, argument} when not is_nil(argument) <-
{:arg,
Enum.find(
query.action.arguments,
&(&1.name == argument || to_string(&1.name) == argument)
)},
argument =
Enum.find(
query.action.arguments,
&(&1.name == argument || to_string(&1.name) == argument)
)
with {:arg, argument} when not is_nil(argument) <- {:arg, argument},
{:ok, casted} <- Ash.Changeset.cast_input(argument.type, value, argument.constraints),
{:constrained, {:ok, casted}, argument} when not is_nil(casted) <-
{:constrained,
@ -742,17 +743,20 @@ defmodule Ash.Query do
{:arg, nil} ->
query
{:constrained, {:ok, nil}, _argument} ->
query
{:constrained, {:ok, nil}, argument} ->
%{query | arguments: Map.put(query.arguments, argument.name, nil)}
{:constrained, {:error, error}, argument} ->
query = %{query | arguments: Map.put(query.arguments, argument.name, value)}
add_invalid_errors(query, argument, error)
{:error, error} ->
query = %{query | arguments: Map.put(query.arguments, argument.name, value)}
add_invalid_errors(query, argument, error)
:error ->
nil
query = %{query | arguments: Map.put(query.arguments, argument.name, value)}
add_invalid_errors(query, argument, "is invalid")
end
else
%{query | arguments: Map.put(query.arguments, argument, value)}
@ -769,8 +773,11 @@ defmodule Ash.Query do
messages
|> Enum.reduce(query, fn message, query ->
opts = Ash.Changeset.error_to_exception_opts(message, argument)
add_error(query, InvalidArgument.exception(opts))
message
|> Ash.Changeset.error_to_exception_opts(argument)
|> Enum.reduce(query, fn opts, query ->
add_error(query, InvalidArgument.exception(opts))
end)
end)
end

48
test/query_test.exs Normal file
View file

@ -0,0 +1,48 @@
defmodule Ash.Test.QueryTest do
@moduledoc false
use ExUnit.Case, async: true
defmodule User do
@moduledoc false
use Ash.Resource, data_layer: Ash.DataLayer.Ets
ets do
private?(true)
end
actions do
read :read do
primary? true
end
read :by_id do
argument :id, :uuid, allow_nil?: false
filter expr(id == ^arg(:id))
end
create :create
update :update
end
attributes do
uuid_primary_key :id
attribute :name, :string
end
end
defmodule Api do
use Ash.Api
resources do
resource User
end
end
describe "read argument validation" do
test "it returns an appropriate error when an argument is invalid" do
query = Ash.Query.for_read(User, :by_id, %{id: "foobar"})
assert [%Ash.Error.Query.InvalidArgument{field: :id}] = query.errors
end
end
end