bool lua_kernel_base::protected_call(lua_State * L, int nArgs, int nRets, error_handler e_h) { int errcode = luaW_pcall_internal(L, nArgs, nRets); if (errcode != LUA_OK) { char const * msg = lua_tostring(L, -1); std::string context = "When executing, "; if (errcode == LUA_ERRRUN) { context += "Lua runtime error: "; } else if (errcode == LUA_ERRERR) { context += "Lua error in attached debugger: "; } else if (errcode == LUA_ERRMEM) { context += "Lua out of memory error: "; } else if (errcode == LUA_ERRGCMM) { context += "Lua error in garbage collection metamethod: "; } else { context += "unknown lua error: "; } if(lua_isstring(L, -1)) { context += msg ? msg : "null string"; } else { context += lua_typename(L, lua_type(L, -1)); } lua_pop(L, 1); e_h(context.c_str(), "Lua Error"); return false; } return true; }
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error) { int res = luaW_pcall_internal(L, nArgs, nRets); if (res) { /* * When an exception is thrown which doesn't derive from * std::exception m will be nullptr pointer. */ char const *m = lua_tostring(L, -1); if(m) { if (allow_wml_error && strncmp(m, "~wml:", 5) == 0) { m += 5; char const *e = strstr(m, "stack traceback"); lg::wml_error() << std::string(m, e ? e - m : strlen(m)); } else if (allow_wml_error && strncmp(m, "~lua:", 5) == 0) { m += 5; char const *e = nullptr, *em = m; while (em[0] && ((em = strstr(em + 1, "stack traceback")))) #ifdef _MSC_VER #pragma warning (pop) #endif e = em; chat_message("Lua error", std::string(m, e ? e - m : strlen(m))); } else { ERR_LUA << m << '\n'; chat_message("Lua error", m); } } else { chat_message("Lua caught unknown exception", ""); } lua_pop(L, 1); return false; } return true; }