From 405bfe40f0fee65351b699649732bb399884e76b Mon Sep 17 00:00:00 2001 From: Ilya Verbin <iverbin@tarantool.org> Date: Fri, 22 Apr 2022 19:05:00 +0300 Subject: [PATCH] console: handle internal.format_yaml exceptions Currently the call to internal.format_yaml in output_handlers["yaml"] is covered by pcall only for `status == true`, however the opposite case also can raise an exception. This patch adds the missed exception handling. Two distinct calls are required, because it is not possible to assing variadic arguments (...) to a variable if some of them is nil. If the first call fails, internal.format_yaml will be called for the second time. Hopefully, it will not fail during formatting of the error message received from libyaml. Before: ``` tarantool> require('net.box').self:call('\x80') LuajitError: builtin/box/console.lua:710: expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS fatal error, exiting the event loop ~/test$ echo $? 0 ~/test$ ``` After: ``` tarantool> require('net.box').self:call('\x80') --- - error: 'console: an exception occurred when formatting the output: expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS' ... tarantool> ``` Part of #6781 Part of #6934 NO_DOC=bugfix NO_TEST=see later commits NO_CHANGELOG=see later commits --- src/box/lua/console.lua | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/box/lua/console.lua b/src/box/lua/console.lua index 69d9d99210..5aeaad41d4 100644 --- a/src/box/lua/console.lua +++ b/src/box/lua/console.lua @@ -51,23 +51,24 @@ local output_handlers = { } local output_eos = { ["yaml"] = '\n...\n', ["lua"] = ';' } output_handlers["yaml"] = function(status, opts, ...) - local err + local err, ok, res + -- Using pcall, because serializer can raise an exception if status then - -- serializer can raise an exception - status, err = pcall(internal.format_yaml, ...) - if status then - return err - else - err = 'console: an exception occurred when formatting the output: '.. - tostring(err) - end + ok, res = pcall(internal.format_yaml, ...) else err = ... if err == nil then err = box.NULL end + ok, res = pcall(internal.format_yaml, { error = err }) + end + if ok then + return res + else + local m = 'console: exception while formatting the output: "%s"' + err = m:format(tostring(res)) + return internal.format_yaml({ error = err }) end - return internal.format_yaml({ error = err }) end -- -- GitLab