From 62e014a08cd27d446f01b9e9f6be36f63ee96f12 Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja.osipov@gmail.com> Date: Fri, 16 Dec 2011 19:15:03 +0400 Subject: [PATCH] A fix and a test case for Bug#901674 A fix and a test case for Bug#901674 "No way to inspect exceptions from Box in Lua" Implenent pcall which works correctly with Objective C exceptions. --- core/tarantool_lua.m | 34 +++++++++++++++++++++++++++++++++- doc/user/stored-programs.xml | 2 +- test/box/lua.result | 22 ++++++++++++++++++++++ test/box/lua.test | 8 ++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/core/tarantool_lua.m b/core/tarantool_lua.m index a9d6efa087..04f6dcb3de 100644 --- a/core/tarantool_lua.m +++ b/core/tarantool_lua.m @@ -435,7 +435,7 @@ box_lua_fiber_run(void *arg __attribute__((unused))) * cancel() is synchronous. */ lua_settop(L, 0); /* pop any possible garbage */ - lua_pushboolean(L, 0); /* completion status */ + lua_pushboolean(L, false); /* completion status */ lua_pushstring(L, e->errmsg); /* error message */ } @finally { /* @@ -699,6 +699,37 @@ lbox_print(struct lua_State *L) return 0; } +/** + * Redefine lua 'pcall' built-in to correctly handle exceptions, + * produced by 'box' C functions. + * + * See Lua documentation on 'pcall' for additional information. + */ + +static int +lbox_pcall(struct lua_State *L) +{ + /* + * Lua pcall() returns true/false for completion status + * plus whatever the called function returns. + */ + @try { + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + lua_pushboolean(L, true); /* push completion status */ + lua_insert(L, 1); /* move 'true' to stack start */ + } @catch (ClientError *e) { + /* + * Note: FiberCancelException passes through this + * catch and thus leaves garbage on coroutine + * stack. + */ + lua_settop(L, 0); /* pop any possible garbage */ + lua_pushboolean(L, false); /* completion status */ + lua_pushstring(L, e->errmsg); /* error message */ + } + return lua_gettop(L); +} + /** A helper to register a single type metatable. */ void tarantool_lua_register_type(struct lua_State *L, const char *type_name, @@ -731,6 +762,7 @@ tarantool_lua_init() lua_pop(L, 1); tarantool_lua_register_type(L, fiberlib_name, lbox_fiber_meta); lua_register(L, "print", lbox_print); + lua_register(L, "pcall", lbox_pcall); L = mod_lua_init(L); lua_settop(L, 0); /* clear possible left-overs of init */ return L; diff --git a/doc/user/stored-programs.xml b/doc/user/stored-programs.xml index 13dbc13b21..cb2c0fc2d6 100644 --- a/doc/user/stored-programs.xml +++ b/doc/user/stored-programs.xml @@ -155,7 +155,7 @@ Call ERROR, Space 99 is disabled (ER_SPACE_DISABLED) localhost> lua pcall(box.insert, 99, 1, 'test') --- - false - - C++ exception + - Space 99 is disabled ... </computeroutput></programlisting> </para> diff --git a/test/box/lua.result b/test/box/lua.result index 5ed71536b4..358715c3a2 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -806,3 +806,25 @@ Found 25 tuples: lua box.space[0]:truncate() --- ... + +# A test case for Bug#901674 +# No way to inspect exceptions from Box in Lua + +lua pcall(box.insert, 99, 1, 'test') +--- + - false + - Space 99 is disabled +... +lua pcall(box.insert, 0, 1, 'hello') +--- + - true + - 1: {'hello'} +... +lua pcall(box.insert, 0, 1, 'hello') +--- + - false + - Tuple already exists +... +lua box.space[0]:truncate() +--- +... diff --git a/test/box/lua.test b/test/box/lua.test index 0a856b8b42..f43352b283 100644 --- a/test/box/lua.test +++ b/test/box/lua.test @@ -234,3 +234,11 @@ exec admin "lua box.space[0]:insert(4, 'world')" exec admin "lua box.space[0]:insert(5, 'hello world')" exec sql "call box.crossjoin('0', '0', '10000')" exec admin "lua box.space[0]:truncate()" +print """ +# A test case for Bug#901674 +# No way to inspect exceptions from Box in Lua +""" +exec admin "lua pcall(box.insert, 99, 1, 'test')" +exec admin "lua pcall(box.insert, 0, 1, 'hello')" +exec admin "lua pcall(box.insert, 0, 1, 'hello')" +exec admin "lua box.space[0]:truncate()" -- GitLab