Skip to content

Commit c4d03b7

Browse files
no1semanDifferentialOrange
authored andcommitted
Fix returning data and error for multiple resolvers
32c97f0 introduced returning data and errors acc. spec #7.1.2 but previous implementation didn't take into account that execution may include multiple resolvers and each of them may return both data and errors. This PR fixes the logic to collect all errors from all resolvers into a single array that can be returned to requester. Based on PR #19 by @no1seman
1 parent 1a2f46b commit c4d03b7

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

graphql/execute.lua

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,6 @@ end
313313

314314
evaluateSelections = function(objectType, object, selections, context)
315315
local result = {}
316-
local errors
317316
local err
318317
local fields = collectFields(objectType, selections, {}, {}, context)
319318
for _, field in ipairs(fields) do
@@ -322,14 +321,14 @@ evaluateSelections = function(objectType, object, selections, context)
322321
result[field.name], err = getFieldEntry(objectType, object, {field.selection},
323322
context)
324323
if err ~= nil then
325-
errors = errors or {}
326-
table.insert(errors, err)
324+
context.errors = context.errors or {}
325+
table.insert(context.errors, err)
327326
end
328327
if result[field.name] == nil then
329328
result[field.name] = box.NULL
330329
end
331330
end
332-
return result, errors
331+
return result, context.errors
333332
end
334333

335334
local function execute(schema, tree, rootValue, variables, operationName)

test/integration/graphql_test.lua

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,4 +1158,49 @@ function g.test_both_data_and_error_result()
11581158
{message = 'Simple error A'},
11591159
{message = 'Simple error B'},
11601160
})
1161+
1162+
query = [[{
1163+
prefix {
1164+
test_A: test(arg: "A")
1165+
test_B: test(arg: "B")
1166+
}
1167+
}]]
1168+
1169+
local function callback_external()
1170+
return {}, {message = 'Simple error from external resolver'}
1171+
end
1172+
1173+
local function callback_internal(_, args)
1174+
return args[1].value, {message = 'Simple error from internal resolver ' .. args[1].value}
1175+
end
1176+
1177+
query_schema = {
1178+
['prefix'] = {
1179+
kind = types.object({
1180+
name = 'prefix',
1181+
fields = {
1182+
['test'] = {
1183+
kind = types.string.nonNull,
1184+
arguments = {
1185+
arg = types.string.nonNull,
1186+
arg2 = types.string,
1187+
arg3 = types.int,
1188+
arg4 = types.long,
1189+
},
1190+
resolve = callback_internal,
1191+
}
1192+
},
1193+
}),
1194+
arguments = {},
1195+
resolve = callback_external,
1196+
}
1197+
}
1198+
1199+
data, errors = check_request(query, query_schema)
1200+
t.assert_equals(data, {prefix = {test_A = 'A', test_B = 'B'}})
1201+
t.assert_equals(errors, {
1202+
{message = "Simple error from internal resolver A"},
1203+
{message = "Simple error from internal resolver B"},
1204+
{message = "Simple error from external resolver"},
1205+
}, "Errors from each resolver were returned")
11611206
end

0 commit comments

Comments
 (0)