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

Commit 2efbf58

Browse files
committed
Add limit reaching error codes
Fixes #134.
1 parent 785f062 commit 2efbf58

File tree

4 files changed

+64
-25
lines changed

4 files changed

+64
-25
lines changed

graphql/accessor_general.lua

+19-10
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ local bit = require('bit')
1313
local rex, is_pcre2 = utils.optional_require_rex()
1414
local avro_helpers = require('graphql.avro_helpers')
1515
local db_schema_helpers = require('graphql.db_schema_helpers')
16+
local error_codes = require('graphql.error_codes')
1617

1718
local check = utils.check
19+
local e = error_codes
1820

1921
-- XXX: consider using [1] when it will be mature enough;
2022
-- look into [2] for the status.
@@ -856,12 +858,17 @@ local function process_tuple(self, state, tuple, opts)
856858
local resulting_object_cnt_max = opts.resulting_object_cnt_max
857859
local fetched_object_cnt_max = opts.fetched_object_cnt_max
858860
qstats.fetched_object_cnt = qstats.fetched_object_cnt + 1
859-
assert(qstats.fetched_object_cnt <= fetched_object_cnt_max,
860-
('fetched object count (%d) exceeds fetched_object_cnt_max limit (%d)')
861-
:format(qstats.fetched_object_cnt, fetched_object_cnt_max))
862-
assert(qcontext.deadline_clock > clock.monotonic64(),
863-
('query execution timeout exceeded timeout_ms limit (%s ms)'):format(
864-
tostring(self.settings.timeout_ms)))
861+
if qstats.fetched_object_cnt > fetched_object_cnt_max then
862+
error(e.fetched_objects_limit_exceeded(
863+
('fetched objects count (%d) exceeds fetched_object_cnt_max ' ..
864+
'limit (%d)'):format(qstats.fetched_object_cnt,
865+
fetched_object_cnt_max)))
866+
end
867+
if clock.monotonic64() > qcontext.deadline_clock then
868+
error(e.timeout_exceeded((
869+
'query execution timeout exceeded timeout_ms limit (%s ms)'):format(
870+
tostring(self.settings.timeout_ms))))
871+
end
865872
local collection_name = opts.collection_name
866873
local pcre = opts.pcre
867874
local resolveField = opts.resolveField
@@ -913,10 +920,12 @@ local function process_tuple(self, state, tuple, opts)
913920
state.objs[#state.objs + 1] = obj
914921
state.count = state.count + 1
915922
qstats.resulting_object_cnt = qstats.resulting_object_cnt + 1
916-
assert(qstats.resulting_object_cnt <= resulting_object_cnt_max,
917-
('resulting objects count (%d) exceeds resulting_object_cnt_max ' ..
918-
'limit (%d)'):format(qstats.resulting_object_cnt,
919-
resulting_object_cnt_max))
923+
if qstats.resulting_object_cnt > resulting_object_cnt_max then
924+
error(e.resulting_objects_limit_exceeded(
925+
('resulting objects count (%d) exceeds resulting_object_cnt_max ' ..
926+
'limit (%d)'):format(qstats.resulting_object_cnt,
927+
resulting_object_cnt_max)))
928+
end
920929
if limit ~= nil and state.count >= limit then
921930
return false
922931
end

graphql/error_codes.lua

+27-8
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,42 @@ local error_codes = {}
22

33
error_codes.TYPE_MISMATCH = 1
44
error_codes.WRONG_VALUE = 2
5+
error_codes.TIMEOUT_EXCEEDED = 3
6+
error_codes.FETCHED_OBJECTS_LIMIT_EXCEEDED = 4
7+
error_codes.RESULTING_OBJECTS_LIMIT_EXCEEDED = 5
58

6-
function error_codes.type_mismatch(message)
9+
local function message_and_error_code_error(message, error_code)
710
return {
811
message = message,
912
extensions = {
10-
error_code = error_codes.TYPE_MISMATCH,
13+
error_code = error_code,
1114
}
1215
}
1316
end
1417

18+
function error_codes.type_mismatch(message)
19+
local error_code = error_codes.TYPE_MISMATCH
20+
return message_and_error_code_error(message, error_code)
21+
end
22+
1523
function error_codes.wrong_value(message)
16-
return {
17-
message = message,
18-
extensions = {
19-
error_code = error_codes.WRONG_VALUE,
20-
}
21-
}
24+
local error_code = error_codes.WRONG_VALUE
25+
return message_and_error_code_error(message, error_code)
26+
end
27+
28+
function error_codes.timeout_exceeded(message)
29+
local error_code = error_codes.TIMEOUT_EXCEEDED
30+
return message_and_error_code_error(message, error_code)
31+
end
32+
33+
function error_codes.fetched_objects_limit_exceeded(message)
34+
local error_code = error_codes.FETCHED_OBJECTS_LIMIT_EXCEEDED
35+
return message_and_error_code_error(message, error_code)
36+
end
37+
38+
function error_codes.resulting_objects_limit_exceeded(message)
39+
local error_code = error_codes.RESULTING_OBJECTS_LIMIT_EXCEEDED
40+
return message_and_error_code_error(message, error_code)
2241
end
2342

2443
return error_codes

test/common/limit_result.test.lua

+12-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ package.path = fio.abspath(debug.getinfo(1).source:match("@?(.*/)")
99
local tap = require('tap')
1010
local test_utils = require('test.test_utils')
1111
local testdata = require('test.testdata.user_order_item_testdata')
12+
local graphql = require('graphql')
13+
14+
local e = graphql.error_codes
1215

1316
local function run_queries(gql_wrapper)
1417
local test = tap.test('result cnt')
@@ -36,10 +39,12 @@ local function run_queries(gql_wrapper)
3639
local result = gql_query:execute(variables)
3740
assert(result.data == nil, "this test should fail")
3841
assert(result.errors ~= nil, "this test should fail")
42+
local exp_err = 'resulting objects count (4) exceeds ' ..
43+
'resulting_object_cnt_max limit (3)'
3944
local err = result.errors[1].message
40-
test:is(err,
41-
'resulting objects count (4) exceeds resulting_object_cnt_max ' ..
42-
'limit (3)', 'resulting_object_cnt_max test')
45+
local code = result.errors[1].extensions.error_code
46+
test:is_deeply({err, code}, {exp_err, e.RESULTING_OBJECTS_LIMIT_EXCEEDED},
47+
'resulting_object_cnt_max test')
4348

4449
variables = {
4550
user_id = 5,
@@ -48,9 +53,11 @@ local function run_queries(gql_wrapper)
4853
local result = gql_query:execute(variables)
4954
assert(result.data == nil, "this test should fail")
5055
assert(result.errors ~= nil, "this test should fail")
56+
local exp_err = 'fetched objects count (6) exceeds ' ..
57+
'fetched_object_cnt_max limit (5)'
5158
local err = result.errors[1].message
52-
test:is(err,
53-
'fetched object count (6) exceeds fetched_object_cnt_max limit (5)',
59+
local code = result.errors[1].extensions.error_code
60+
test:is_deeply({err, code}, {exp_err, e.FETCHED_OBJECTS_LIMIT_EXCEEDED},
5461
'fetched_object_cnt_max test')
5562

5663
assert(test:check(), 'check plan')

test/common/query_timeout.test.lua

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ package.path = fio.abspath(debug.getinfo(1).source:match("@?(.*/)")
99
local tap = require('tap')
1010
local test_utils = require('test.test_utils')
1111
local testdata = require('test.testdata.user_order_item_testdata')
12+
local graphql = require('graphql')
13+
14+
local e = graphql.error_codes
1215

1316
local function run_queries(gql_wrapper)
1417
local test = tap.test('result cnt')
@@ -34,9 +37,10 @@ local function run_queries(gql_wrapper)
3437
local result = gql_query:execute(variables)
3538
assert(result.data == nil, "this test should fail")
3639
assert(result.errors ~= nil, "this test should fail")
40+
local exp_err = 'query execution timeout exceeded timeout_ms limit (0.001 ms)'
3741
local err = result.errors[1].message
38-
test:is(err, 'query execution timeout exceeded timeout_ms limit (0.001 ms)',
39-
'timeout test')
42+
local code = result.errors[1].extensions.error_code
43+
test:is_deeply({err, code}, {exp_err, e.TIMEOUT_EXCEEDED}, 'timeout test')
4044

4145
assert(test:check(), 'check plan')
4246
end

0 commit comments

Comments
 (0)