diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc index fc53a40f44187616a178d4f97225bb1ebe60c7c5..6a6280566efac316fdb74c18cacaa67de53ade04 100644 --- a/src/box/lua/error.cc +++ b/src/box/lua/error.cc @@ -154,6 +154,16 @@ luaT_error_clear(lua_State *L) return 0; } +static int +luaT_error_set(struct lua_State *L) +{ + if (lua_gettop(L) == 0) + return luaL_error(L, "Usage: box.error.set(error)"); + struct error *e = luaL_checkerror(L, 1); + diag_set_error(&fiber()->diag, e); + return 0; +} + static int lbox_errinj_set(struct lua_State *L) { @@ -268,6 +278,10 @@ box_lua_error_init(struct lua_State *L) { lua_pushcfunction(L, luaT_error_new); lua_setfield(L, -2, "new"); } + { + lua_pushcfunction(L, luaT_error_set); + lua_setfield(L, -2, "set"); + } lua_setfield(L, -2, "__index"); } lua_setmetatable(L, -2); diff --git a/src/lua/error.c b/src/lua/error.c index d82e78dc475dc8197675ec5ec7b5183001b5f5b0..18a990a888117b4f197f81bff403412181d7d363 100644 --- a/src/lua/error.c +++ b/src/lua/error.c @@ -53,7 +53,7 @@ luaL_iserror(struct lua_State *L, int narg) return e; } -static struct error * +struct error * luaL_checkerror(struct lua_State *L, int narg) { struct error *error = luaL_iserror(L, narg); diff --git a/src/lua/error.h b/src/lua/error.h index 64fa5eba3621ed32da2c82793250c2dd36e2974c..16cdaf7fe1b890110db26320dd26c0f6421d4aee 100644 --- a/src/lua/error.h +++ b/src/lua/error.h @@ -65,6 +65,9 @@ luaT_pusherror(struct lua_State *L, struct error *e); struct error * luaL_iserror(struct lua_State *L, int narg); +struct error * +luaL_checkerror(struct lua_State *L, int narg); + void tarantool_lua_error_init(struct lua_State *L); diff --git a/test/box/error.result b/test/box/error.result index 9b6c8b4628063e0018682abc40763954d415b78f..31b2ce52becc8196da667fbfab93c3d5fb1fffee 100644 --- a/test/box/error.result +++ b/test/box/error.result @@ -436,6 +436,42 @@ test_run:cmd("setopt delimiter ''"); | --- | - true | ... + +-- gh-4778: don't add created via box.error.new() errors to +-- Tarantool's diagnostic area. +-- +err = box.error.new({code = 111, reason = "cause"}) + | --- + | ... +assert(box.error.last() ~= err) + | --- + | - error: assertion failed! + | ... +box.error.set(err) + | --- + | ... +assert(box.error.last() == err) + | --- + | - true + | ... +-- Consider wrong or tricky inputs to box.error.set() +-- +box.error.set(1) + | --- + | - error: 'Invalid argument #1 (error expected, got number)' + | ... +box.error.set(nil) + | --- + | - error: 'Invalid argument #1 (error expected, got nil)' + | ... +box.error.set(box.error.last()) + | --- + | ... +assert(box.error.last() == err) + | --- + | - true + | ... + space:drop() | --- | ... diff --git a/test/box/error.test.lua b/test/box/error.test.lua index d16cc5672984f75b3d67e1e2cac12230135d5e19..81591ea7e7400d024c2e3a470376e724daf94715 100644 --- a/test/box/error.test.lua +++ b/test/box/error.test.lua @@ -77,4 +77,19 @@ end; t; test_run:cmd("setopt delimiter ''"); + +-- gh-4778: don't add created via box.error.new() errors to +-- Tarantool's diagnostic area. +-- +err = box.error.new({code = 111, reason = "cause"}) +assert(box.error.last() ~= err) +box.error.set(err) +assert(box.error.last() == err) +-- Consider wrong or tricky inputs to box.error.set() +-- +box.error.set(1) +box.error.set(nil) +box.error.set(box.error.last()) +assert(box.error.last() == err) + space:drop()