首先來(lái)看最最普通的一個(gè) json 解析的例子(被解析的 json 字符串是錯(cuò)誤的,缺少一個(gè)雙引號(hào)):
-- http://www.kyne.com.au/~mark/software/lua-cjson.php
-- version: 2.1 devel
local json = require("cjson")
local str = [[ {"key:"value"} ]]
local t = json.decode(str)
ngx.say(" --> ", type(t))
-- ... do the other things
ngx.say("all fine")
代碼執(zhí)行錯(cuò)誤日志如下:
2015/06/27 00:01:42 [error] 2714#0: *25 lua entry thread aborted: runtime error: ...ork/git/github.com/lua-resty-memcached-server/t/test.lua:8: Expected colon but found invalid token at character 9
stack traceback:
coroutine 0:
[C]: in function 'decode'
...ork/git/github.com/lua-resty-memcached-server/t/test.lua:8: in function <...ork/git/github.com/lua-resty-memcached-server/t/test.lua:1>, client: 127.0.0.1, server: localhost, request: "GET /test HTTP/1.1", host: "127.0.0.1:8001"
這可不是期望結(jié)果:decode 失敗,500 錯(cuò)誤直接退了。改良了一下代碼:
local json = require("cjson")
local function _json_decode(str)
return json.decode(str)
end
function json_decode( str )
local ok, t = pcall(_json_decode, str)
if not ok then
return nil
end
return t
end
如果需要在 Lua 中處理錯(cuò)誤,必須使用函數(shù) pcall(protected call)來(lái)包裝需要執(zhí)行的代碼。 pcall 接收一個(gè)函數(shù)和要傳遞給后者的參數(shù),并執(zhí)行,執(zhí)行結(jié)果:有錯(cuò)誤、無(wú)錯(cuò)誤;返回值 true 或者或 false, errorinfo。pcall 以一種"保護(hù)模式"來(lái)調(diào)用第一個(gè)參數(shù),因此 pcall 可以捕獲函數(shù)執(zhí)行中的任何錯(cuò)誤。有興趣的同學(xué),請(qǐng)更多了解下 Lua 中的異常處理。
另外,可以使用 CJSON 2.1.0
,該版本新增一個(gè) cjson.safe
模塊接口,該接口兼容 cjson
模塊,并且在解析錯(cuò)誤時(shí)不拋出異常,而是返回 nil
。
local json = require("cjson.safe")
local str = [[ {"key:"value"} ]]
local t = json.decode(str)
if t then
ngx.say(" --> ", type(t))
end