[PATCH 1/8] lua: fix box.error.raise
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Mon Apr 16 21:39:11 MSK 2018
It did not work because raise is implemented as __index metatable
member, and error() is __call metatable member. The second one
takes additional implicit argument - self.
---
src/box/lua/error.cc | 78 +++++++++++++++++++++++++++++++++-----------------
test/box/misc.result | 39 +++++++++++++++++++++++++
test/box/misc.test.lua | 18 ++++++++++++
3 files changed, 108 insertions(+), 27 deletions(-)
diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc
index 314907421..56cc2c563 100644
--- a/src/box/lua/error.cc
+++ b/src/box/lua/error.cc
@@ -42,25 +42,18 @@ extern "C" {
#include "lua/utils.h"
#include "box/error.h"
-static int
-luaT_error_raise(lua_State *L)
+static void
+luaT_error_create(lua_State *L, int top, int top_base)
{
uint32_t code = 0;
const char *reason = NULL;
const char *file = "";
unsigned line = 0;
lua_Debug info;
- /* lua_type(L, 1) == LUA_TTABLE - box.error table */
- int top = lua_gettop(L);
- if (top <= 1) {
- /* re-throw saved exceptions (if any) */
- if (box_error_last())
- luaT_error(L);
- return 0;
- } else if (top >= 2 && lua_type(L, 2) == LUA_TNUMBER) {
- code = lua_tonumber(L, 2);
+ if (top >= top_base && lua_type(L, top_base) == LUA_TNUMBER) {
+ code = lua_tonumber(L, top_base);
reason = tnt_errcode_desc(code);
- if (top > 2) {
+ if (top > top_base) {
/* Call string.format(reason, ...) to format message */
lua_getglobal(L, "string");
if (lua_isnil(L, -1))
@@ -69,24 +62,29 @@ luaT_error_raise(lua_State *L)
if (lua_isnil(L, -1))
goto raise;
lua_pushstring(L, reason);
- for (int i = 3; i <= top; i++)
+ for (int i = top_base + 1; i <= top; i++)
lua_pushvalue(L, i);
- lua_call(L, top - 1, 1);
+ lua_call(L, top - top_base + 1, 1);
reason = lua_tostring(L, -1);
} else if (strchr(reason, '%') != NULL) {
/* Missing arguments to format string */
luaL_error(L, "box.error(): bad arguments");
}
- } else if (top == 2 && lua_istable(L, 2)) {
- /* A special case that rethrows raw error (used by net.box) */
- lua_getfield(L, 2, "code");
- code = lua_tonumber(L, -1);
- lua_pop(L, 1);
- lua_getfield(L, 2, "reason");
- reason = lua_tostring(L, -1);
- if (reason == NULL)
- reason = "";
- lua_pop(L, 1);
+ } else if (top == top_base) {
+ if (lua_istable(L, top_base)) {
+ /* A special case that rethrows raw error (used by net.box) */
+ lua_getfield(L, top_base, "code");
+ code = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ lua_getfield(L, top_base, "reason");
+ reason = lua_tostring(L, -1);
+ if (reason == NULL)
+ reason = "";
+ lua_pop(L, 1);
+ } else if (luaL_iserror(L, top_base)) {
+ lua_error(L);
+ return;
+ }
} else {
luaL_error(L, "box.error(): bad arguments");
}
@@ -104,8 +102,34 @@ raise:
}
say_debug("box.error() at %s:%i", file, line);
box_error_set(file, line, code, "%s", reason);
- luaT_error(L);
- return 0;
+}
+
+static int
+luaT_error_call(lua_State *L)
+{
+ int top = lua_gettop(L);
+ if (top <= 1) {
+ /* Re-throw saved exceptions if any. */
+ if (box_error_last())
+ luaT_error(L);
+ return 0;
+ }
+ luaT_error_create(L, top, 2);
+ return luaT_error(L);
+}
+
+static int
+luaT_error_raise(lua_State *L)
+{
+ int top = lua_gettop(L);
+ if (top == 0) {
+ /* Re-throw saved exceptions if any. */
+ if (box_error_last())
+ luaT_error(L);
+ return 0;
+ }
+ luaT_error_create(L, top, 1);
+ return luaT_error(L);
}
static int
@@ -214,7 +238,7 @@ box_lua_error_init(struct lua_State *L) {
}
lua_newtable(L);
{
- lua_pushcfunction(L, luaT_error_raise);
+ lua_pushcfunction(L, luaT_error_call);
lua_setfield(L, -2, "__call");
lua_newtable(L);
diff --git a/test/box/misc.result b/test/box/misc.result
index 57717c4fe..2102e4a1c 100644
--- a/test/box/misc.result
+++ b/test/box/misc.result
@@ -176,6 +176,45 @@ box.error(box.error.UNSUPPORTED)
---
- error: 'box.error(): bad arguments'
...
+--
+-- box.error.raise not worked because it is __index method of
+-- box.error and box.error() is the __call method. The second
+-- one takes itself as the first argument.
+--
+box.error(box.error.CREATE_SPACE, "space", "error")
+---
+- error: 'Failed to create space ''space'': error'
+...
+box.error()
+---
+- error: 'Failed to create space ''space'': error'
+...
+box.error.raise()
+---
+- error: 'Failed to create space ''space'': error'
+...
+box.error.raise(box.error.CREATE_SPACE, "space", "error")
+---
+- error: 'Failed to create space ''space'': error'
+...
+box.error.raise(box.error.UNKNOWN)
+---
+- error: Unknown error
+...
+--
+-- Allow to rethrow error.
+--
+_, err = pcall(box.error, box.error.UNKNOWN)
+---
+...
+box.error(err)
+---
+- error: Unknown error
+...
+box.error.raise(err)
+---
+- error: Unknown error
+...
----------------
-- # box.stat
----------------
diff --git a/test/box/misc.test.lua b/test/box/misc.test.lua
index b7bf600c3..299dc830f 100644
--- a/test/box/misc.test.lua
+++ b/test/box/misc.test.lua
@@ -52,6 +52,24 @@ box.error(box.error.UNSUPPORTED, "x", "x%s")
box.error(box.error.UNSUPPORTED, "x")
box.error(box.error.UNSUPPORTED)
+--
+-- box.error.raise not worked because it is __index method of
+-- box.error and box.error() is the __call method. The second
+-- one takes itself as the first argument.
+--
+box.error(box.error.CREATE_SPACE, "space", "error")
+box.error()
+box.error.raise()
+box.error.raise(box.error.CREATE_SPACE, "space", "error")
+box.error.raise(box.error.UNKNOWN)
+
+--
+-- Allow to rethrow error.
+--
+_, err = pcall(box.error, box.error.UNKNOWN)
+box.error(err)
+box.error.raise(err)
+
----------------
-- # box.stat
----------------
--
2.15.1 (Apple Git-101)
More information about the Tarantool-patches
mailing list