Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Commit 7fc9c49

Browse files
committed
Add TYPE_MISMATCH and WRONG_VALUE error codes
Part of #134.
1 parent a8b3650 commit 7fc9c49

File tree

10 files changed

+285
-132
lines changed

10 files changed

+285
-132
lines changed

graphql/convert_schema/union.lua

+20-12
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ local yaml = require('yaml')
22
local core_types = require('graphql.core.types')
33
local avro_helpers = require('graphql.avro_helpers')
44
local helpers = require('graphql.convert_schema.helpers')
5-
5+
local error_codes = require('graphql.error_codes')
66
local utils = require('graphql.utils')
7+
78
local check = utils.check
9+
local e = error_codes
810

911
local union = {}
1012

@@ -303,28 +305,34 @@ function union.convert(avro_schema, opts)
303305
types = union_types,
304306
name = helpers.full_name(union_name, context),
305307
resolveType = function(result)
306-
assert(type(result) == 'table',
307-
'union value must be a map with one field, got ' ..
308-
type(result))
309-
assert(next(result) ~= nil and next(result, next(result)) == nil,
310-
'union value must have only one field')
308+
if type(result) ~= 'table' then
309+
error(e.wrong_value('union value must be a map with one ' ..
310+
'field, got ' .. type(result)))
311+
end
312+
if next(result) == nil or next(result, next(result)) ~= nil then
313+
error(e.wrong_value('union value must have only one field'))
314+
end
311315
for determinant, type in pairs(determinant_to_type) do
312316
if result[determinant] ~= nil then
313317
return type
314318
end
315319
end
316320
local field_name = tostring(next(result))
317-
error(('unexpected union value field: %s'):format(field_name))
321+
error(e.wrong_value(('unexpected union value field: %s'):format(
322+
field_name)))
318323
end,
319324
resolveNodeType = function(node)
320-
assert(#node.values == 1,
321-
('box object with more then one field: %d'):format(
322-
#node.values))
325+
if #node.values ~= 1 then
326+
error(e.wrong_value('box object with more then one field: %d')
327+
:format(#node.values))
328+
end
323329
local determinant = node.values[1].name
324330
check(determinant, 'determinant', 'string')
325331
local res = determinant_to_type[determinant]
326-
assert(determinant ~= nil,
327-
('the union has no "%s" field'):format(determinant))
332+
if res == nil then
333+
error(e.wrong_value('the union has no "%s" field'):format(
334+
determinant))
335+
end
328336
return res
329337
end,
330338
})

graphql/core/rules.lua

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ local types = require(path .. '.types')
33
local util = require(path .. '.util')
44
local introspection = require(path .. '.introspection')
55
local query_util = require(path .. '.query_util')
6+
local graphql_error_codes = require('graphql.error_codes')
67
local graphql_utils = require('graphql.utils')
78

9+
local e = graphql_error_codes
10+
811
local function getParentField(context, name, count)
912
if introspection.fieldMap[name] then return introspection.fieldMap[name] end
1013

@@ -593,7 +596,7 @@ function rules.variableUsageAllowed(node, context)
593596
local ok, err = isVariableTypesValid(argument, argumentType, context,
594597
variableMap)
595598
if not ok then
596-
error(err)
599+
error(e.type_mismatch(err))
597600
end
598601
end
599602
end

graphql/core/util.lua

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
local yaml = require('yaml')
2+
local graphql_error_codes = require('graphql.error_codes')
3+
4+
local e = graphql_error_codes
25

36
local util = {}
47

@@ -79,8 +82,8 @@ function util.coerceValue(node, schemaType, variables, opts)
7982
if schemaType.__type == 'NonNull' then
8083
local res = util.coerceValue(node, schemaType.ofType, variables, opts)
8184
if strict_non_null and res == nil then
82-
error(('Expected non-null for "%s", got null'):format(
83-
util.getTypeName(schemaType)))
85+
error(e.wrong_value(('Expected non-null for "%s", got null'):format(
86+
util.getTypeName(schemaType))))
8487
end
8588
return res
8689
end
@@ -95,7 +98,7 @@ function util.coerceValue(node, schemaType, variables, opts)
9598

9699
if schemaType.__type == 'List' then
97100
if node.kind ~= 'list' then
98-
error('Expected a list')
101+
error(e.wrong_value('Expected a list'))
99102
end
100103

101104
return util.map(node.values, function(value)
@@ -111,7 +114,7 @@ function util.coerceValue(node, schemaType, variables, opts)
111114

112115
if isInputObject then
113116
if node.kind ~= 'inputObject' then
114-
error('Expected an input object')
117+
error(e.wrong_value('Expected an input object'))
115118
end
116119

117120
-- check all fields: as from value as well as from schema
@@ -128,7 +131,8 @@ function util.coerceValue(node, schemaType, variables, opts)
128131
local inputObjectValue = {}
129132
for fieldName, _ in pairs(fieldNameSet) do
130133
if not schemaType.fields[fieldName] then
131-
error('Unknown input object field "' .. fieldName .. '"')
134+
error(e.wrong_value(('Unknown input object field "%s"'):format(
135+
fieldName)))
132136
end
133137

134138
local childValue = fieldValues[fieldName]
@@ -142,7 +146,7 @@ function util.coerceValue(node, schemaType, variables, opts)
142146

143147
if isInputMap then
144148
if node.kind ~= 'inputObject' then
145-
error('Expected an input object')
149+
error(e.wrong_value('Expected an input object'))
146150
end
147151

148152
local inputMapValue = {}
@@ -156,11 +160,11 @@ function util.coerceValue(node, schemaType, variables, opts)
156160

157161
if schemaType.__type == 'Enum' then
158162
if node.kind ~= 'enum' then
159-
error('Expected enum value, got ' .. node.kind)
163+
error(e.wrong_value('Expected enum value, got %s'):format(node.kind))
160164
end
161165

162166
if not schemaType.values[node.value] then
163-
error('Invalid enum value "' .. node.value .. '"')
167+
error(e.wrong_value('Invalid enum value "%s"'):format(node.value))
164168
end
165169

166170
return node.value
@@ -173,7 +177,8 @@ function util.coerceValue(node, schemaType, variables, opts)
173177

174178
if schemaType.__type == 'Scalar' then
175179
if schemaType.parseLiteral(node) == nil then
176-
error('Could not coerce "' .. tostring(node.value) .. '" to "' .. schemaType.name .. '"')
180+
error(e.wrong_value('Could not coerce "%s" to "%s"'):format(
181+
tostring(node.value), schemaType.name))
177182
end
178183

179184
return schemaType.parseLiteral(node)

graphql/core/validate_variables.lua

+47-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
local types = require('graphql.core.types')
22
local graphql_utils = require('graphql.utils')
3+
local graphql_error_codes = require('graphql.error_codes')
34

45
local check = graphql_utils.check
6+
local e = graphql_error_codes
57

68
local validate_variables = {}
79

@@ -14,8 +16,10 @@ local function checkVariableValue(variableName, value, variableType)
1416

1517
if isNonNull then
1618
variableType = types.nullable(variableType)
17-
assert(value ~= nil,
18-
('Variable "%s" expected to be non-null'):format(variableName))
19+
if value == nil then
20+
error(e.wrong_value(('Variable "%s" expected to be non-null'):format(
21+
variableName)))
22+
end
1923
end
2024

2125
local isList = variableType.__type == 'List'
@@ -29,12 +33,14 @@ local function checkVariableValue(variableName, value, variableType)
2933
if value == nil then return end
3034

3135
if isList then
32-
assert(type(value) == 'table',
33-
('Variable "%s" for a List must be a Lua table, got %s')
34-
:format(variableName, type(value)))
35-
assert(graphql_utils.is_array(value),
36-
('Variable "%s" for a List must be an array, got map')
37-
:format(variableName))
36+
if type(value) ~= 'table' then
37+
error(e.wrong_value(('Variable "%s" for a List must be a Lua ' ..
38+
'table, got %s'):format(variableName, type(value))))
39+
end
40+
if not graphql_utils.is_array(value) then
41+
error(e.wrong_value(('Variable "%s" for a List must be an array, ' ..
42+
'got map'):format(variableName)))
43+
end
3844
assert(variableType.ofType ~= nil, 'variableType.ofType must not be nil')
3945
for i, item in ipairs(value) do
4046
local itemName = variableName .. '[' .. tostring(i) .. ']'
@@ -44,9 +50,11 @@ local function checkVariableValue(variableName, value, variableType)
4450
end
4551

4652
if isInputObject then
47-
assert(type(value) == 'table',
48-
('Variable "%s" for the InputObject "%s" must be a Lua table, ' ..
49-
'got %s'):format(variableName, variableType.name, type(value)))
53+
if type(value) ~= 'table' then
54+
error(e.wrong_value(('Variable "%s" for the InputObject "%s" must ' ..
55+
'be a Lua table, got %s'):format(variableName, variableType.name,
56+
type(value))))
57+
end
5058

5159
-- check all fields: as from value as well as from schema
5260
local fieldNameSet = {}
@@ -59,13 +67,16 @@ local function checkVariableValue(variableName, value, variableType)
5967

6068
for fieldName, _ in pairs(fieldNameSet) do
6169
local fieldValue = value[fieldName]
62-
assert(type(fieldName) == 'string',
63-
('Field key of the variable "%s" for the InputObject "%s" ' ..
64-
'must be a string, got %s'):format(variableName, variableType.name,
65-
type(fieldName)))
66-
assert(type(variableType.fields[fieldName]) ~= 'nil',
67-
('Unknown field "%s" of the variable "%s" for the ' ..
68-
'InputObject "%s"'):format(fieldName, variableName, variableType.name))
70+
if type(fieldName) ~= 'string' then
71+
error(e.wrong_value(('Field key of the variable "%s" for the ' ..
72+
'InputObject "%s" must be a string, got %s'):format(variableName,
73+
variableType.name, type(fieldName))))
74+
end
75+
if type(variableType.fields[fieldName]) == 'nil' then
76+
error(e.wrong_value(('Unknown field "%s" of the variable "%s" ' ..
77+
'for the InputObject "%s"'):format(fieldName, variableName,
78+
variableType.name)))
79+
end
6980

7081
local childType = variableType.fields[fieldName].kind
7182
local childName = variableName .. '.' .. fieldName
@@ -76,15 +87,18 @@ local function checkVariableValue(variableName, value, variableType)
7687
end
7788

7889
if isInputMap then
79-
assert(type(value) == 'table',
80-
('Variable "%s" for the InputMap "%s" must be a Lua table, got %s')
81-
:format(variableName, variableType.name, type(value)))
90+
if type(value) ~= 'table' then
91+
error(e.wrong_value(('Variable "%s" for the InputMap "%s" must be a ' ..
92+
'Lua table, got %s'):format(variableName, variableType.name,
93+
type(value))))
94+
end
8295

8396
for fieldName, fieldValue in pairs(value) do
84-
assert(type(fieldName) == 'string',
85-
('Field key of the variable "%s" for the InputMap "%s" must be a ' ..
86-
'string, got %s'):format(variableName, variableType.name,
87-
type(fieldName)))
97+
if type(fieldName) ~= 'string' then
98+
error(e.wrong_value(('Field key of the variable "%s" for the ' ..
99+
'InputMap "%s" must be a string, got %s'):format(variableName,
100+
variableType.name, type(fieldName))))
101+
end
88102
local childType = variableType.values
89103
local childName = variableName .. '.' .. fieldName
90104
checkVariableValue(childName, fieldValue, childType)
@@ -103,9 +117,10 @@ local function checkVariableValue(variableName, value, variableType)
103117

104118
if isScalar then
105119
check(variableType.isValueOfTheType, 'isValueOfTheType', 'function')
106-
assert(variableType.isValueOfTheType(value),
107-
('Wrong variable "%s" for the Scalar "%s"'):format(
108-
variableName, variableType.name))
120+
if not variableType.isValueOfTheType(value) then
121+
error(e.wrong_value(('Wrong variable "%s" for the Scalar "%s"'):format(
122+
variableName, variableType.name)))
123+
end
109124
return
110125
end
111126

@@ -115,8 +130,10 @@ end
115130
function validate_variables.validate_variables(context)
116131
-- check that all variable values have corresponding variable declaration
117132
for variableName, _ in pairs(context.variables or {}) do
118-
assert(context.variableTypes[variableName] ~= nil,
119-
('There is no declaration for the variable "%s"'):format(variableName))
133+
if context.variableTypes[variableName] == nil then
134+
error(e.wrong_value(('There is no declaration for the variable "%s"')
135+
:format(variableName)))
136+
end
120137
end
121138

122139
-- check that variable values have correct type

graphql/error_codes.lua

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
local error_codes = {}
2+
3+
error_codes.TYPE_MISMATCH = 1
4+
error_codes.WRONG_VALUE = 2
5+
6+
function error_codes.type_mismatch(message)
7+
return {
8+
message = message,
9+
extensions = {
10+
error_code = error_codes.TYPE_MISMATCH,
11+
}
12+
}
13+
end
14+
15+
function error_codes.wrong_value(message)
16+
return {
17+
message = message,
18+
extensions = {
19+
error_code = error_codes.WRONG_VALUE,
20+
}
21+
}
22+
end
23+
24+
return error_codes

graphql/init.lua

+9
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,21 @@ local accessor_general = require('graphql.accessor_general')
3434
local accessor_space = require('graphql.accessor_space')
3535
local accessor_shard = require('graphql.accessor_shard')
3636
local impl = require('graphql.impl')
37+
local error_codes = require('graphql.error_codes')
3738

3839
local graphql = {}
3940

4041
-- constants
4142
graphql.TIMEOUT_INFINITY = accessor_general.TIMEOUT_INFINITY
4243

44+
-- error codes
45+
graphql.error_codes = {}
46+
for k, v in pairs(error_codes) do
47+
if type(v) == 'number' then
48+
graphql.error_codes[k] = v
49+
end
50+
end
51+
4352
-- for backward compatibility
4453
graphql.accessor_general = accessor_general
4554
graphql.accessor_space = accessor_space

0 commit comments

Comments
 (0)