diff --git a/lib/absinthe/federation/schema/entities_field.ex b/lib/absinthe/federation/schema/entities_field.ex index 140b4a6..b49c581 100644 --- a/lib/absinthe/federation/schema/entities_field.ex +++ b/lib/absinthe/federation/schema/entities_field.ex @@ -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) @@ -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 diff --git a/test/absinthe/federation/schema/entities_field_test.exs b/test/absinthe/federation/schema/entities_field_test.exs index d8046a6..b3a477d 100644 --- a/test/absinthe/federation/schema/entities_field_test.exs +++ b/test/absinthe/federation/schema/entities_field_test.exs @@ -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) @@ -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 { diff --git a/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs b/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs index 9d370e2..4172b6c 100644 --- a/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs +++ b/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs @@ -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 @@ -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