This is an automated email from the ASF dual-hosted git repository.
nic-6443 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new ed5ca9e8e fix: normalize qjson errors in request json (#13407)
ed5ca9e8e is described below
commit ed5ca9e8e1b26587d07d653d3c62ee4b5f673208
Author: Nic <[email protected]>
AuthorDate: Thu May 21 16:03:26 2026 +0800
fix: normalize qjson errors in request json (#13407)
---
apisix/core/request_json.lua | 44 ++++++++++++++++++++++++++++++++++-------
t/core/request.t | 47 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/apisix/core/request_json.lua b/apisix/core/request_json.lua
index 90ec9a058..d635681f6 100644
--- a/apisix/core/request_json.lua
+++ b/apisix/core/request_json.lua
@@ -19,6 +19,8 @@ local config_local = require("apisix.core.config_local")
local core_json = require("apisix.core.json")
local qjson = require("qjson")
local simdjson = require("resty.simdjson")
+local pcall = pcall
+local tostring = tostring
local simdjson_parser, simdjson_err = simdjson.new()
@@ -28,6 +30,39 @@ local configured_name
local _M = {}
+local function qjson_decode(str)
+ local ok, decoded, err = pcall(qjson.decode, str)
+ if not ok then
+ return nil, tostring(decoded)
+ end
+
+ if decoded == nil then
+ return nil, err
+ end
+
+ ok, decoded, err = pcall(qjson.materialize, decoded)
+ if not ok then
+ return nil, tostring(decoded)
+ end
+
+ if decoded == nil then
+ return nil, err
+ end
+
+ return decoded
+end
+
+
+local function qjson_encode(data)
+ local ok, encoded, err = pcall(qjson.encode, data)
+ if not ok then
+ return nil, tostring(encoded)
+ end
+
+ return encoded, err
+end
+
+
function _M.decode(str)
if not configured_name then
configured_name =
config_local.local_conf().apisix.request_body_json_lib
@@ -42,12 +77,7 @@ function _M.decode(str)
return simdjson_parser:decode(str)
end
- local decoded, err = qjson.decode(str)
- if not decoded then
- return nil, err
- end
-
- return qjson.materialize(decoded)
+ return qjson_decode(str)
end
@@ -57,7 +87,7 @@ function _M.encode(data)
end
if configured_name == "qjson" then
- return qjson.encode(data)
+ return qjson_encode(data)
end
-- simdjson encode is slower than cjson, so simdjson mode only uses it for
decode.
diff --git a/t/core/request.t b/t/core/request.t
index fb72d075e..d0d4c145f 100644
--- a/t/core/request.t
+++ b/t/core/request.t
@@ -629,7 +629,50 @@ cjson encode: {"lib":"body"}
-=== TEST 19: simdjson preserves empty arrays for cjson encoding
+=== TEST 19: qjson decode and encode errors are returned
+--- yaml_config
+apisix:
+ request_body_json_lib: qjson
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local request_json = require("apisix.core.request_json")
+
+ ngx.ctx.api_ctx = {}
+
+ local body, body_err = core.request.get_json_request_body_table()
+ ngx.say("body nil: ", body == nil)
+ ngx.say("body error: ", body_err and body_err.message and
+ body_err.message:find("could not parse JSON request
body:", 1, true) == 1)
+
+ local decoded, decode_err = request_json.decode("{")
+ ngx.say("decode nil: ", decoded == nil)
+ ngx.say("decode error: ", type(decode_err) == "string" and
#decode_err > 0)
+
+ local encoded, encode_err = request_json.encode({bad = function()
end})
+ ngx.say("encode nil: ", encoded == nil)
+ ngx.say("encode error: ", type(encode_err) == "string" and
#encode_err > 0)
+ }
+ }
+--- request
+POST /t
+{
+--- more_headers
+Content-Type: application/json
+--- response_body
+body nil: true
+body error: true
+decode nil: true
+decode error: true
+encode nil: true
+encode error: true
+--- no_error_log
+[error]
+
+
+
+=== TEST 20: simdjson preserves empty arrays for cjson encoding
--- yaml_config
apisix:
request_body_json_lib: simdjson
@@ -653,7 +696,7 @@ tags array: true
-=== TEST 20: ai transport encoders use request_json
+=== TEST 21: ai transport encoders use request_json
--- config
location /t {
content_by_lua_block {