diff --git a/.gitignore b/.gitignore index 0df0a90..9d06d94 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ luacov.*.out* /node_modules /package-lock.json *.mo +.history +.vscode diff --git a/graphql/execute.lua b/graphql/execute.lua index 7ebfda6..493b157 100644 --- a/graphql/execute.lua +++ b/graphql/execute.lua @@ -301,30 +301,35 @@ local function getFieldEntry(objectType, object, fields, context) } local resolvedObject, err = (fieldType.resolve or defaultResolver)(object, arguments, info) - if err ~= nil then + if resolvedObject == nil and err ~= nil then error(err) end local subSelections = mergeSelectionSets(fields) return completeValue(fieldType.kind, resolvedObject, subSelections, context, {fieldName = fieldName} - ) + ), err end evaluateSelections = function(objectType, object, selections, context) local result = {} + local errors + local err local fields = collectFields(objectType, selections, {}, {}, context) for _, field in ipairs(fields) do assert(result[field.name] == nil, 'two selections into the one field: ' .. field.name) - result[field.name] = getFieldEntry(objectType, object, {field.selection}, + result[field.name], err = getFieldEntry(objectType, object, {field.selection}, context) - + if err ~= nil then + errors = errors or {} + table.insert(errors, err) + end if result[field.name] == nil then result[field.name] = box.NULL end end - return result + return result, errors end local function execute(schema, tree, rootValue, variables, operationName) diff --git a/test/integration/graphql_test.lua b/test/integration/graphql_test.lua index 7fff396..a4d11e8 100644 --- a/test/integration/graphql_test.lua +++ b/test/integration/graphql_test.lua @@ -1129,3 +1129,33 @@ function g.test_validation_non_null_argument_error() end ) end + +function g.test_both_data_and_error_result() + local query = [[{ + test_A: test(arg: "A") + test_B: test(arg: "B") + }]] + + local function callback(_, args) + return args[1].value, {message = 'Simple error ' .. args[1].value} + end + + local query_schema = { + ['test'] = { + kind = types.string.nonNull, + arguments = { + arg = types.string.nonNull, + arg2 = types.string, + arg3 = types.int, + arg4 = types.long, + }, + resolve = callback, + } + } + local data, errors = check_request(query, query_schema) + t.assert_equals(data, {test_A = 'A', test_B = 'B'}) + t.assert_equals(errors, { + {message = 'Simple error A'}, + {message = 'Simple error B'}, + }) +end