mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Use a Lua error handler that calls tostring (#11913)
This commit is contained in:
parent
1f3b5e553b
commit
0fc97a1483
@ -6,6 +6,9 @@
|
|||||||
--
|
--
|
||||||
|
|
||||||
-- Initialize some very basic things
|
-- Initialize some very basic things
|
||||||
|
function core.error_handler(err, level)
|
||||||
|
return debug.traceback(tostring(err), level)
|
||||||
|
end
|
||||||
do
|
do
|
||||||
local function concat_args(...)
|
local function concat_args(...)
|
||||||
local n, t = select("#", ...), {...}
|
local n, t = select("#", ...), {...}
|
||||||
|
@ -9956,3 +9956,17 @@ Bit Library
|
|||||||
Functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap
|
Functions: bit.tobit, bit.tohex, bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift, bit.arshift, bit.rol, bit.ror, bit.bswap
|
||||||
|
|
||||||
See http://bitop.luajit.org/ for advanced information.
|
See http://bitop.luajit.org/ for advanced information.
|
||||||
|
|
||||||
|
Error Handling
|
||||||
|
--------------
|
||||||
|
|
||||||
|
When an error occurs that is not caught, Minetest calls the function
|
||||||
|
`minetest.error_handler` with the error object as its first argument. The second
|
||||||
|
argument is the stack level where the error occurred. The return value is the
|
||||||
|
error string that should be shown. By default this is a backtrace from
|
||||||
|
`debug.traceback`. If the error object is not a string, it is first converted
|
||||||
|
with `tostring` before being displayed. This means that you can use tables as
|
||||||
|
error objects so long as you give them `__tostring` metamethods.
|
||||||
|
|
||||||
|
You can override `minetest.error_handler`. You should call the previous handler
|
||||||
|
with the correct stack level in your implementation.
|
||||||
|
@ -27,10 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
std::string script_get_backtrace(lua_State *L)
|
std::string script_get_backtrace(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE);
|
lua_getglobal(L, "debug");
|
||||||
|
lua_getfield(L, -1, "traceback");
|
||||||
lua_call(L, 0, 1);
|
lua_call(L, 0, 1);
|
||||||
std::string result = luaL_checkstring(L, -1);
|
std::string result = luaL_checkstring(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 2);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +47,25 @@ int script_exception_wrapper(lua_State *L, lua_CFunction f)
|
|||||||
return lua_error(L); // Rethrow as a Lua error.
|
return lua_error(L); // Rethrow as a Lua error.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int script_error_handler(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_getglobal(L, "core");
|
||||||
|
lua_getfield(L, -1, "error_handler");
|
||||||
|
if (!lua_isnil(L, -1)) {
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
} else {
|
||||||
|
// No Lua error handler available. Call debug.traceback(tostring(#1), level).
|
||||||
|
lua_getglobal(L, "debug");
|
||||||
|
lua_getfield(L, -1, "traceback");
|
||||||
|
lua_getglobal(L, "tostring");
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_call(L, 1, 1);
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, 2); // Stack level
|
||||||
|
lua_call(L, 2, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that we can't get tracebacks for LUA_ERRMEM or LUA_ERRERR (without
|
* Note that we can't get tracebacks for LUA_ERRMEM or LUA_ERRERR (without
|
||||||
* hacking Lua internals). For LUA_ERRMEM, this is because memory errors will
|
* hacking Lua internals). For LUA_ERRMEM, this is because memory errors will
|
||||||
|
@ -54,7 +54,7 @@ enum {
|
|||||||
CUSTOM_RIDX_SCRIPTAPI,
|
CUSTOM_RIDX_SCRIPTAPI,
|
||||||
CUSTOM_RIDX_GLOBALS_BACKUP,
|
CUSTOM_RIDX_GLOBALS_BACKUP,
|
||||||
CUSTOM_RIDX_CURRENT_MOD_NAME,
|
CUSTOM_RIDX_CURRENT_MOD_NAME,
|
||||||
CUSTOM_RIDX_BACKTRACE,
|
CUSTOM_RIDX_ERROR_HANDLER,
|
||||||
CUSTOM_RIDX_HTTP_API_LUA,
|
CUSTOM_RIDX_HTTP_API_LUA,
|
||||||
CUSTOM_RIDX_METATABLE_MAP,
|
CUSTOM_RIDX_METATABLE_MAP,
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ enum {
|
|||||||
|
|
||||||
// Pushes the error handler onto the stack and returns its index
|
// Pushes the error handler onto the stack and returns its index
|
||||||
#define PUSH_ERROR_HANDLER(L) \
|
#define PUSH_ERROR_HANDLER(L) \
|
||||||
(lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE), lua_gettop((L)))
|
(lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER), lua_gettop((L)))
|
||||||
|
|
||||||
#define PCALL_RESL(L, RES) { \
|
#define PCALL_RESL(L, RES) { \
|
||||||
int result_ = (RES); \
|
int result_ = (RES); \
|
||||||
@ -121,6 +121,8 @@ enum RunCallbacksMode
|
|||||||
std::string script_get_backtrace(lua_State *L);
|
std::string script_get_backtrace(lua_State *L);
|
||||||
// Wrapper for CFunction calls that converts C++ exceptions to Lua errors
|
// Wrapper for CFunction calls that converts C++ exceptions to Lua errors
|
||||||
int script_exception_wrapper(lua_State *L, lua_CFunction f);
|
int script_exception_wrapper(lua_State *L, lua_CFunction f);
|
||||||
|
// Acts as the error handler for lua_pcall
|
||||||
|
int script_error_handler(lua_State *L);
|
||||||
// Takes an error from lua_pcall and throws it as a LuaError
|
// Takes an error from lua_pcall and throws it as a LuaError
|
||||||
void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
|
void script_error(lua_State *L, int pcall_result, const char *mod, const char *fxn);
|
||||||
|
|
||||||
|
@ -103,11 +103,8 @@ ScriptApiBase::ScriptApiBase(ScriptingType type):
|
|||||||
#endif
|
#endif
|
||||||
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
|
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
|
||||||
|
|
||||||
// Add and save an error handler
|
lua_pushcfunction(m_luastack, script_error_handler);
|
||||||
lua_getglobal(m_luastack, "debug");
|
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
|
||||||
lua_getfield(m_luastack, -1, "traceback");
|
|
||||||
lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_BACKTRACE);
|
|
||||||
lua_pop(m_luastack, 1); // pop debug
|
|
||||||
|
|
||||||
// Add a C++ wrapper function to catch exceptions thrown in Lua -> C++ calls
|
// Add a C++ wrapper function to catch exceptions thrown in Lua -> C++ calls
|
||||||
#if USE_LUAJIT
|
#if USE_LUAJIT
|
||||||
|
Loading…
Reference in New Issue
Block a user