Skip to content

Commit

Permalink
Handle nil results for entity queries (#98)
Browse files Browse the repository at this point in the history
Returns resolved entity as `nil` instead of causing an error
  • Loading branch information
jeffutter authored Jun 17, 2024
1 parent 477aa09 commit ac9d6cd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
15 changes: 9 additions & 6 deletions lib/absinthe/federation/schema/entities_field.ex
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,14 @@ defmodule Absinthe.Federation.Schema.EntitiesField do
resolution.arguments.representations
|> Enum.reduce(%{errors: [], value: []}, fn r, acc ->
case Map.get(value, r) do
{:error, err} -> Map.update!(acc, :errors, &[err | &1])
result -> Map.update!(acc, :value, &[result | &1])
{:error, err} ->
Map.update!(acc, :errors, &[err | &1])

{result, errors} ->
acc |> Map.update!(:value, &[result | &1]) |> Map.update!(:errors, &(errors ++ &1))

result ->
Map.update!(acc, :value, &[result | &1])
end
end)

Expand Down Expand Up @@ -242,10 +248,7 @@ defmodule Absinthe.Federation.Schema.EntitiesField do
}

defp reduce_resolution(%{state: :resolved} = res) do
case res.value do
nil -> {res.arguments.representation, {:error, res.errors |> List.first()}}
_ -> {res.arguments.representation, res.value}
end
{res.arguments.representation, {res.value, res.errors}}
end

defp reduce_resolution(%{middleware: []} = res), do: res
Expand Down
30 changes: 30 additions & 0 deletions test/absinthe/federation/schema/entities_field_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do
case upc do
"123" -> {:ok, args}
"456" -> {:ok, args}
"nil" <> _ -> {:ok, nil}
_ -> {:error, "Couldn't find product with upc #{upc}"}
end
end)
Expand Down Expand Up @@ -145,6 +146,35 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do
} = resp
end

test "Handles missing data" do
query = """
query {
_entities(representations: [
{
__typename: "Product",
upc: "nil1"
},
{
__typename: "Product",
upc: "nil22"
}
]) {
__typename
...on Product {
upc
foo
}
}
}
"""

{:ok, resp} = Absinthe.run(query, ResolverSchema, variables: %{})

assert %{
data: %{"_entities" => [nil, nil]}
} = resp
end

test "falls back to default _resolve_reference implementation" do
query = """
query {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ defmodule Absinthe.Federation.Schema.PersistentTermSchemaEntityFieldTest do
resolve(fn
_, %{name: "John"}, _ -> {:ok, %{__typename: "Person", name: "John", age: 20}}
_, %{name: "Acme"}, _ -> {:ok, %{__typename: "Business", name: "Acme", employee_count: 10}}
_, %{name: "nil" <> _}, _ -> {:ok, nil}
end)
end

Expand Down Expand Up @@ -83,4 +84,39 @@ defmodule Absinthe.Federation.Schema.PersistentTermSchemaEntityFieldTest do
}
} = resp
end

test "Handles missing data" do
query = """
query {
_entities(representations: [
{ __typename: "NamedEntity", name: "John" },
{ __typename: "NamedEntity", name: "nilJohn" },
{ __typename: "NamedEntity", name: "nilAcme" }
]) {
...on NamedEntity {
__typename
name
... on Person {
age
}
... on Business {
employeeCount
}
}
}
}
"""

{:ok, resp} = Absinthe.run(query, EntitySchemaWithPersistentTermProvider, variables: %{})

assert %{
data: %{
"_entities" => [
%{"__typename" => "Person", "name" => "John", "age" => 20},
nil,
nil
]
}
} = resp
end
end

0 comments on commit ac9d6cd

Please sign in to comment.