From ad79f6b4d9deceb9af2c49ad160487b4faf00b7e Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tsisyk.com> Date: Tue, 20 Jan 2015 13:45:10 +0300 Subject: [PATCH] Fix #643: exception handling in console --- src/lua/console.lua | 33 +++++++++++++++++++++------------ test/app/console.result | 4 +++- test/app/console.test.lua | 10 +++++++++- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/lua/console.lua b/src/lua/console.lua index 11fd8000f8..dc0541f68c 100644 --- a/src/lua/console.lua +++ b/src/lua/console.lua @@ -24,19 +24,28 @@ local function format(status, ...) local function wrapnull(v) return v == nil and formatter.NULL or v end - if not status then - local v = ... - return formatter.encode({{error = wrapnull(v) }}) - end - local count = select('#', ...) - if count == 0 then - return "---\n...\n" - end - local res = {} - for i=1,count,1 do - table.insert(res, wrapnull(select(i, ...))) + local err + if status then + local count = select('#', ...) + if count == 0 then + return "---\n...\n" + end + local res = {} + for i=1,count,1 do + table.insert(res, wrapnull(select(i, ...))) + end + -- serializer can raise an exception + status, err = pcall(formatter.encode, res) + if status then + return err + else + err = 'console: an exception occurred during formatting result: '.. + tostring(err) + end + else + err = wrapnull(...) end - return formatter.encode(res) + return formatter.encode({{error = err }}) end -- diff --git a/test/app/console.result b/test/app/console.result index 40596ba7e4..0f603e1514 100644 --- a/test/app/console.result +++ b/test/app/console.result @@ -1,5 +1,5 @@ TAP version 13 -1..26 +1..28 ok - console.listen started ok - Handshake ok - connect to console @@ -18,6 +18,8 @@ ok - remote eval ok - remote state.remote.host ok - remote state.remote.port ok - remote state.prompt +ok - exception handling +ok - exception handling ok - remote disconnect ok - console.listen stopped ok - console.listen uri support diff --git a/test/app/console.test.lua b/test/app/console.test.lua index 680edb1463..483b3e4ecd 100755 --- a/test/app/console.test.lua +++ b/test/app/console.test.lua @@ -20,7 +20,7 @@ local EOL = "\n%.%.%.\n" test = tap.test("console") -test:plan(26) +test:plan(28) -- Start console and connect to it local server = console.listen(CONSOLE_SOCKET) @@ -98,6 +98,14 @@ test:is(state.remote.port, IPROTO_SOCKET, "remote state.remote.port") test:is(state.prompt, string.format("%s:%s", "unix/", IPROTO_SOCKET), "remote state.prompt") +-- Check exception handling (gh-643) +client:write("error('test')\n") +test:ok(yaml.decode(client:read(EOL))[1].error:match('test') ~= nil, + "exception handling") +client:write("setmetatable({}, { __serialize = function() error('test') end})\n") +test:ok(yaml.decode(client:read(EOL))[1].error:match('test') ~= nil, + "exception handling") + -- Disconnect from iproto client:write("~.\n") -- Check that iproto console has been disconnected -- GitLab