From 66be21510148a922879815edd02ce16c67c2a58a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 19 Nov 2024 07:26:28 +0300 Subject: [PATCH] add advanced lua errors handler & fix hud script source path in traceback --- res/scripts/stdmin.lua | 7 +++++++ src/frontend/screens/LevelScreen.cpp | 7 ++++++- src/logic/scripting/lua/lua_util.cpp | 15 ++++++++++++--- src/logic/scripting/scripting_hud.cpp | 7 +++++-- src/logic/scripting/scripting_hud.hpp | 6 +++++- 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 219ac5cb..996af40e 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -307,3 +307,10 @@ function __scripts_cleanup() end end end + +function __vc__error(msg, frame) + if events then + events.emit("core:error", msg, debug.get_traceback(1)) + end + return debug.traceback(msg, frame) +end diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index fed19cdd..1acd9200 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -83,7 +83,12 @@ void LevelScreen::initializePack(ContentPackRuntime* pack) { const ContentPack& info = pack->getInfo(); fs::path scriptFile = info.folder/fs::path("scripts/hud.lua"); if (fs::is_regular_file(scriptFile)) { - scripting::load_hud_script(pack->getEnvironment(), info.id, scriptFile); + scripting::load_hud_script( + pack->getEnvironment(), + info.id, + scriptFile, + pack->getId() + ":scripts/hud.lua" + ); } } diff --git a/src/logic/scripting/lua/lua_util.cpp b/src/logic/scripting/lua/lua_util.cpp index 44583e4c..86419906 100644 --- a/src/logic/scripting/lua/lua_util.cpp +++ b/src/logic/scripting/lua/lua_util.cpp @@ -145,10 +145,14 @@ static int l_error_handler(lua_State* L) { if (!isstring(L, 1)) { // 'message' not a string? return 1; // keep it intact } - if (get_from(L, "debug", "traceback")) { + if (getglobal(L, "__vc__error")) { lua_pushvalue(L, 1); // pass error message lua_pushinteger(L, 2); // skip this function and traceback lua_call(L, 2, 1); // call debug.traceback + } if (get_from(L, "debug", "traceback")) { + lua_pushvalue(L, 1); + lua_pushinteger(L, 2); + lua_call(L, 2, 1); } return 1; } @@ -172,8 +176,13 @@ int lua::call_nothrow(State* L, int argc, int nresults) { pushcfunction(L, l_error_handler); insert(L, handler_pos); if (lua_pcall(L, argc, LUA_MULTRET, handler_pos)) { - log_error(tostring(L, -1)); - pop(L); + auto errorstr = tostring(L, -1); + if (errorstr) { + log_error(errorstr); + pop(L); + } else { + log_error(""); + } remove(L, handler_pos); return 0; } diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index 41fb163f..a7be1892 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -76,13 +76,16 @@ void scripting::on_frontend_close() { } void scripting::load_hud_script( - const scriptenv& senv, const std::string& packid, const fs::path& file + const scriptenv& senv, + const std::string& packid, + const fs::path& file, + const std::string& fileName ) { int env = *senv; std::string src = files::read_string(file); logger.info() << "loading script " << file.u8string(); - lua::execute(lua::get_main_state(), env, src, file.u8string()); + lua::execute(lua::get_main_state(), env, src, fileName); register_event(env, "init", packid + ":.init"); register_event(env, "on_hud_open", packid + ":.hudopen"); diff --git a/src/logic/scripting/scripting_hud.hpp b/src/logic/scripting/scripting_hud.hpp index cea7e8ec..7eed738c 100644 --- a/src/logic/scripting/scripting_hud.hpp +++ b/src/logic/scripting/scripting_hud.hpp @@ -22,7 +22,11 @@ namespace scripting { /// @param env environment id /// @param packid content-pack id /// @param file script file path + /// @param fileName script file path using the engine format void load_hud_script( - const scriptenv &env, const std::string &packid, const fs::path &file + const scriptenv& env, + const std::string& packid, + const fs::path& file, + const std::string& fileName ); }