mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
Lua scripting: improve error reporting.
When calling Lua scripts we try to report not just the error but information about the code line causing the error.
This commit is contained in:
parent
b96ba52cfa
commit
51adc6e1bc
@ -620,6 +620,26 @@ void scriptingInit(void) {
|
|||||||
lua_pcall(lua,0,0,0);
|
lua_pcall(lua,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a helper function we use for pcall error reporting.
|
||||||
|
* Note that when the error is in the C function we want to report the
|
||||||
|
* information about the caller, that's what makes sense from the point
|
||||||
|
* of view of the user debugging a script. */
|
||||||
|
{
|
||||||
|
char *errh_func = "function __redis__err__handler(err)\n"
|
||||||
|
" local i = debug.getinfo(2,'nSl')\n"
|
||||||
|
" if i and i.what == 'C' then\n"
|
||||||
|
" i = debug.getinfo(3,'nSl')\n"
|
||||||
|
" end\n"
|
||||||
|
" if i then\n"
|
||||||
|
" return err ..': '.. i.source .. ': ' .. i.currentline\n"
|
||||||
|
" else\n"
|
||||||
|
" return err\n"
|
||||||
|
" end\n"
|
||||||
|
"end\n";
|
||||||
|
luaL_loadbuffer(lua,errh_func,strlen(errh_func),"@err_handler_def");
|
||||||
|
lua_pcall(lua,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create the (non connected) client that we use to execute Redis commands
|
/* Create the (non connected) client that we use to execute Redis commands
|
||||||
* inside the Lua interpreter.
|
* inside the Lua interpreter.
|
||||||
* Note: there is no need to create it again when this function is called
|
* Note: there is no need to create it again when this function is called
|
||||||
@ -840,21 +860,25 @@ void evalGenericCommand(redisClient *c, int evalsha) {
|
|||||||
funcname[42] = '\0';
|
funcname[42] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Push the pcall error handler function on the stack. */
|
||||||
|
lua_getglobal(lua, "__redis__err__handler");
|
||||||
|
|
||||||
/* Try to lookup the Lua function */
|
/* Try to lookup the Lua function */
|
||||||
lua_getglobal(lua, funcname);
|
lua_getglobal(lua, funcname);
|
||||||
if (lua_isnil(lua,1)) {
|
if (lua_isnil(lua,-1)) {
|
||||||
lua_pop(lua,1); /* remove the nil from the stack */
|
lua_pop(lua,1); /* remove the nil from the stack */
|
||||||
/* Function not defined... let's define it if we have the
|
/* Function not defined... let's define it if we have the
|
||||||
* body of the function. If this is an EVALSHA call we can just
|
* body of the function. If this is an EVALSHA call we can just
|
||||||
* return an error. */
|
* return an error. */
|
||||||
if (evalsha) {
|
if (evalsha) {
|
||||||
|
lua_pop(lua,1); /* remove the error handler from the stack. */
|
||||||
addReply(c, shared.noscripterr);
|
addReply(c, shared.noscripterr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
|
if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
|
||||||
/* Now the following is guaranteed to return non nil */
|
/* Now the following is guaranteed to return non nil */
|
||||||
lua_getglobal(lua, funcname);
|
lua_getglobal(lua, funcname);
|
||||||
redisAssert(!lua_isnil(lua,1));
|
redisAssert(!lua_isnil(lua,-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate the argv and keys table accordingly to the arguments that
|
/* Populate the argv and keys table accordingly to the arguments that
|
||||||
@ -881,7 +905,7 @@ void evalGenericCommand(redisClient *c, int evalsha) {
|
|||||||
* already defined, we can call it. We have zero arguments and expect
|
* already defined, we can call it. We have zero arguments and expect
|
||||||
* a single return value. */
|
* a single return value. */
|
||||||
|
|
||||||
err = lua_pcall(lua,0,1,0);
|
err = lua_pcall(lua,0,1,-2);
|
||||||
|
|
||||||
/* Perform some cleanup that we need to do both on error and success. */
|
/* Perform some cleanup that we need to do both on error and success. */
|
||||||
if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
|
if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user