Merge pull request #17459 from rktjmp/lua-error-tostring

feat: __tostring lua errors if possible before showing in messages
This commit is contained in:
bfredl 2022-03-18 00:57:48 +01:00 committed by GitHub
commit c1b98cfa5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 1 deletions

View File

@ -92,7 +92,22 @@ static void nlua_error(lua_State *const lstate, const char *const msg)
FUNC_ATTR_NONNULL_ALL
{
size_t len;
const char *const str = lua_tolstring(lstate, -1, &len);
const char *str = NULL;
if (luaL_getmetafield(lstate, -1, "__tostring")) {
if (lua_isfunction(lstate, -1) && luaL_callmeta(lstate, -2, "__tostring")) {
// call __tostring, convert the result and pop result.
str = lua_tolstring(lstate, -1, &len);
lua_pop(lstate, 1);
}
// pop __tostring.
lua_pop(lstate, 1);
}
if (!str) {
// defer to lua default conversion, this will render tables as [NULL].
str = lua_tolstring(lstate, -1, &len);
}
msg_ext_set_kind("lua_error");
semsg_multiline(msg, (int)len, str);

View File

@ -61,6 +61,44 @@ describe('print', function()
eq('Vim(lua):E5108: Error executing lua E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>',
pcall_err(command, 'lua print("foo", v_tblout, "bar")'))
end)
it('coerces error values into strings', function()
write_file(fname, [[
function string_error() error("my mistake") end
function number_error() error(1234) end
function nil_error() error(nil) end
function table_error() error({message = "my mistake"}) end
function custom_error()
local err = {message = "my mistake", code = 11234}
setmetatable(err, {
__tostring = function(t)
return "Internal Error [" .. t.code .. "] " .. t.message
end
})
error(err)
end
function bad_custom_error()
local err = {message = "my mistake", code = 11234}
setmetatable(err, {
-- intentionally not a function, downstream programmer has made an mistake
__tostring = "Internal Error [" .. err.code .. "] " .. err.message
})
error(err)
end
]])
eq('', exec_capture('luafile ' .. fname))
eq('Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:0: my mistake',
pcall_err(command, 'lua string_error()'))
eq('Vim(lua):E5108: Error executing lua Xtest-functional-lua-overrides-luafile:0: 1234',
pcall_err(command, 'lua number_error()'))
eq('Vim(lua):E5108: Error executing lua [NULL]',
pcall_err(command, 'lua nil_error()'))
eq('Vim(lua):E5108: Error executing lua [NULL]',
pcall_err(command, 'lua table_error()'))
eq('Vim(lua):E5108: Error executing lua Internal Error [11234] my mistake',
pcall_err(command, 'lua custom_error()'))
eq('Vim(lua):E5108: Error executing lua [NULL]',
pcall_err(command, 'lua bad_custom_error()'))
end)
it('prints strings with NULs and NLs correctly', function()
meths.set_option('more', true)
eq('abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n',