Skip to content

Commit 89d9cda

Browse files
authored
Fix error repathing for object namespaces (#118)
1 parent 8a85957 commit 89d9cda

File tree

4 files changed

+131
-15
lines changed

4 files changed

+131
-15
lines changed

lib/graphql/stitching/executor/boundary_source.rb

-2
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,7 @@ def repath_errors!(pathed_errors_by_object_id, forward_path, current_path=[], ro
183183
end
184184

185185
elsif forward_path.any?
186-
current_path << index
187186
repath_errors!(pathed_errors_by_object_id, forward_path, current_path, scope)
188-
current_path.pop
189187

190188
elsif scope.is_a?(Array)
191189
scope.each_with_index do |element, index|

lib/graphql/stitching/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
module GraphQL
44
module Stitching
5-
VERSION = "1.2.0"
5+
VERSION = "1.2.1"
66
end
77
end

test/graphql/stitching/integration/errors_test.rb

+81-10
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,18 @@ def setup
99
"a" => Schemas::Errors::ElementsA,
1010
"b" => Schemas::Errors::ElementsB,
1111
})
12+
end
1213

13-
@query = %|
14-
query($ids: [ID!]!) {
15-
elementsA(ids: $ids) {
14+
def test_repaths_root_errors
15+
result = plan_and_execute(@supergraph, %|
16+
query {
17+
elementsA(ids: ["10", "18", "36"]) {
1618
name
1719
code
1820
year
1921
}
2022
}
21-
|
22-
end
23-
24-
def test_queries_merged_interfaces
25-
result = plan_and_execute(@supergraph, @query, {
26-
"ids" => ["10", "18", "36"]
27-
})
23+
|)
2824

2925
expected_data = {
3026
"elementsA" => [
@@ -50,4 +46,79 @@ def test_queries_merged_interfaces
5046
assert_equal expected_data, result["data"]
5147
assert_equal expected_errors, result["errors"]
5248
end
49+
50+
def test_repaths_nested_errors_onto_list_source
51+
result = plan_and_execute(@supergraph, %|
52+
query {
53+
elementsA(ids: ["10", "36"]) {
54+
name
55+
isotopes {
56+
name
57+
halflife
58+
}
59+
isotope {
60+
name
61+
halflife
62+
}
63+
}
64+
}
65+
|)
66+
67+
expected_data = {
68+
"elementsA" => [
69+
{
70+
"name" => "neon",
71+
"isotope" => nil,
72+
"isotopes" => [nil],
73+
},
74+
{
75+
"name" => "krypton",
76+
"isotope" => { "name" => "Kr79", "halflife" => "35d" },
77+
"isotopes" => [{ "name" => "Kr79", "halflife" => "35d" }],
78+
},
79+
],
80+
}
81+
82+
expected_errors = [
83+
{ "message" => "Not found", "path" => ["elementsA", 0, "isotopes", 0] },
84+
{ "message" => "Not found", "path" => ["elementsA", 0, "isotope"] },
85+
]
86+
87+
assert_equal expected_data, result["data"]
88+
assert_equal expected_errors, result["errors"]
89+
end
90+
91+
def test_repaths_nested_errors_onto_object_source
92+
result = plan_and_execute(@supergraph, %|
93+
query {
94+
elementA(id: "10") {
95+
name
96+
isotopes {
97+
name
98+
halflife
99+
}
100+
isotope {
101+
name
102+
halflife
103+
}
104+
}
105+
}
106+
|)
107+
108+
expected_data = {
109+
"elementA" => {
110+
"name" => "neon",
111+
"isotope" => nil,
112+
"isotopes" => [nil],
113+
},
114+
}
115+
116+
expected_errors = [
117+
{ "message" => "Not found", "path" => ["elementA", "isotopes", 0] },
118+
{ "message" => "Not found", "path" => ["elementA", "isotope"] },
119+
]
120+
121+
assert_equal expected_data, result["data"]
122+
assert_equal expected_errors, result["errors"]
123+
end
53124
end

test/schemas/errors.rb

+49-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,18 @@ class Boundary < GraphQL::Schema::Directive
99
repeatable true
1010
end
1111

12+
ISOTOPES_A = [
13+
{ id: '1', name: 'Ne20' },
14+
{ id: '2', name: 'Kr79' },
15+
].freeze
16+
17+
ISOTOPES_B = [
18+
{ id: '2', halflife: '35d' },
19+
].freeze
20+
1221
ELEMENTS_A = [
13-
{ id: '10', name: 'neon' },
14-
{ id: '36', name: 'krypton' },
22+
{ id: '10', name: 'neon', isotopes: [ISOTOPES_A[0]], isotope: ISOTOPES_A[0] },
23+
{ id: '36', name: 'krypton', isotopes: [ISOTOPES_A[1]], isotope: ISOTOPES_A[1] },
1524
].freeze
1625

1726
ELEMENTS_B = [
@@ -20,9 +29,16 @@ class Boundary < GraphQL::Schema::Directive
2029
].freeze
2130

2231
class ElementsA < GraphQL::Schema
32+
class Isotope < GraphQL::Schema::Object
33+
field :id, ID, null: false
34+
field :name, String, null: false
35+
end
36+
2337
class Element < GraphQL::Schema::Object
2438
field :id, ID, null: false
2539
field :name, String, null: false
40+
field :isotopes, [Isotope, null: true], null: false
41+
field :isotope, Isotope, null: true
2642
end
2743

2844
class Query < GraphQL::Schema::Object
@@ -36,12 +52,34 @@ def elements_a(ids:)
3652
ELEMENTS_A.find { _1[:id] == id } || GraphQL::ExecutionError.new("Not found")
3753
end
3854
end
55+
56+
field :element_a, Element, null: true do
57+
argument :id, ID, required: true
58+
end
59+
60+
def element_a(id:)
61+
ELEMENTS_A.find { _1[:id] == id } || GraphQL::ExecutionError.new("Not found")
62+
end
63+
64+
field :isotope_a, Isotope, null: true do
65+
directive Boundary, key: "id"
66+
argument :id, ID, required: true
67+
end
68+
69+
def isotope_a(id:)
70+
ISOTOPES_A.find { _1[:id] == id } || GraphQL::ExecutionError.new("Not found")
71+
end
3972
end
4073

4174
query Query
4275
end
4376

4477
class ElementsB < GraphQL::Schema
78+
class Isotope < GraphQL::Schema::Object
79+
field :id, ID, null: false
80+
field :halflife, String, null: false
81+
end
82+
4583
class Element < GraphQL::Schema::Object
4684
field :id, ID, null: false
4785
field :code, String, null: true
@@ -59,6 +97,15 @@ def elements_b(ids:)
5997
ELEMENTS_B.find { _1[:id] == id } || GraphQL::ExecutionError.new("Not found")
6098
end
6199
end
100+
101+
field :isotope_b, Isotope, null: true do
102+
directive Boundary, key: "id"
103+
argument :id, ID, required: true
104+
end
105+
106+
def isotope_b(id:)
107+
ISOTOPES_B.find { _1[:id] == id } || GraphQL::ExecutionError.new("Not found")
108+
end
62109
end
63110

64111
query Query

0 commit comments

Comments
 (0)