Skip to content
Permalink
Browse files
Clean up/improve some scriptapi error handling code
  • Loading branch information
sfan5 committed Sep 10, 2021
1 parent 7423c4c commit 766e885a1b1c5afb7a62f11b427b6d135adeab87
@@ -325,6 +325,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
m_access_denied = true;
m_access_denied_reason = reason;
}
inline void setFatalError(const LuaError &e)
{
setFatalError(std::string("Lua :") + e.what());
}

// Renaming accessDeniedReason to better name could be good as it's used to
// disconnect client when CSM failed.
@@ -647,7 +647,7 @@ MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
m_server->getScriptIface()->environment_OnGenerated(
minp, maxp, m_mapgen->blockseed);
} catch (LuaError &e) {
m_server->setAsyncFatalError("Lua: finishGen" + std::string(e.what()));
m_server->setAsyncFatalError(e);
}

/*
@@ -101,42 +101,6 @@ void script_error(lua_State *L, int pcall_result, const char *mod, const char *f
throw LuaError(err_msg);
}

// Push the list of callbacks (a lua table).
// Then push nargs arguments.
// Then call this function, which
// - runs the callbacks
// - replaces the table and arguments with the return value,
// computed depending on mode
void script_run_callbacks_f(lua_State *L, int nargs,
RunCallbacksMode mode, const char *fxn)
{
FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");

// Insert error handler
PUSH_ERROR_HANDLER(L);
int error_handler = lua_gettop(L) - nargs - 1;
lua_insert(L, error_handler);

// Insert run_callbacks between error handler and table
lua_getglobal(L, "core");
lua_getfield(L, -1, "run_callbacks");
lua_remove(L, -2);
lua_insert(L, error_handler + 1);

// Insert mode after table
lua_pushnumber(L, (int) mode);
lua_insert(L, error_handler + 3);

// Stack now looks like this:
// ... <error handler> <run_callbacks> <table> <mode> <arg#1> <arg#2> ... <arg#n>

int result = lua_pcall(L, nargs + 2, 1, error_handler);
if (result != 0)
script_error(L, result, NULL, fxn);

lua_remove(L, error_handler);
}

static void script_log_add_source(lua_State *L, std::string &message, int stack_depth)
{
lua_Debug ar;
@@ -75,9 +75,6 @@ extern "C" {
} \
}

#define script_run_callbacks(L, nargs, mode) \
script_run_callbacks_f((L), (nargs), (mode), __FUNCTION__)

// What script_run_callbacks does with the return values of callbacks.
// Regardless of the mode, if only one callback is defined,
// its return value is the total return value.
@@ -108,16 +105,17 @@ enum RunCallbacksMode
// are converted by readParam<bool> to true or false, respectively.
};

// Gets a backtrace of the current execution point
std::string script_get_backtrace(lua_State *L);
// Wrapper for CFunction calls that converts C++ exceptions to Lua errors
int script_exception_wrapper(lua_State *L, lua_CFunction f);
// 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_run_callbacks_f(lua_State *L, int nargs,
RunCallbacksMode mode, const char *fxn);

bool script_log_unique(lua_State *L, std::string message, std::ostream &log_to,
int stack_depth = 1);

enum class DeprecatedHandlingMode {
enum DeprecatedHandlingMode {
Ignore,
Log,
Error
@@ -128,8 +128,11 @@ class ScriptApiBase : protected LuaHelper {
lua_State* getStack()
{ return m_luastack; }

// Checks that stack size is sane
void realityCheck();
// Takes an error from lua_pcall and throws it as a LuaError
void scriptError(int result, const char *fxn);
// Dumps stack contents for debugging
void stackDump(std::ostream &o);

void setGameDef(IGameDef* gamedef) { m_gamedef = gamedef; }
@@ -33,7 +33,11 @@ void ScriptApiClient::on_mods_loaded()
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_mods_loaded");
// Call callbacks
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
try {
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

void ScriptApiClient::on_shutdown()
@@ -44,7 +48,11 @@ void ScriptApiClient::on_shutdown()
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_shutdown");
// Call callbacks
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
try {
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

bool ScriptApiClient::on_sending_message(const std::string &message)
@@ -56,7 +64,12 @@ bool ScriptApiClient::on_sending_message(const std::string &message)
lua_getfield(L, -1, "registered_on_sending_chat_message");
// Call callbacks
lua_pushstring(L, message.c_str());
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -69,7 +82,12 @@ bool ScriptApiClient::on_receiving_message(const std::string &message)
lua_getfield(L, -1, "registered_on_receiving_chat_message");
// Call callbacks
lua_pushstring(L, message.c_str());
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -82,7 +100,11 @@ void ScriptApiClient::on_damage_taken(int32_t damage_amount)
lua_getfield(L, -1, "registered_on_damage_taken");
// Call callbacks
lua_pushinteger(L, damage_amount);
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

void ScriptApiClient::on_hp_modification(int32_t newhp)
@@ -94,7 +116,11 @@ void ScriptApiClient::on_hp_modification(int32_t newhp)
lua_getfield(L, -1, "registered_on_hp_modification");
// Call callbacks
lua_pushinteger(L, newhp);
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

void ScriptApiClient::on_death()
@@ -105,7 +131,11 @@ void ScriptApiClient::on_death()
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_death");
// Call callbacks
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
try {
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

void ScriptApiClient::environment_step(float dtime)
@@ -120,8 +150,7 @@ void ScriptApiClient::environment_step(float dtime)
try {
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getClient()->setFatalError(std::string("Client environment_step: ") + e.what() + "\n"
+ script_get_backtrace(L));
getClient()->setFatalError(e);
}
}

@@ -146,7 +175,11 @@ void ScriptApiClient::on_formspec_input(const std::string &formname,
lua_pushlstring(L, value.c_str(), value.size());
lua_settable(L, -3);
}
runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
try {
runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
} catch (LuaError &e) {
getClient()->setFatalError(e);
}
}

bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
@@ -164,7 +197,12 @@ bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
pushnode(L, node, ndef);

// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
try {
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return lua_toboolean(L, -1);
}

@@ -183,7 +221,12 @@ bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
pushnode(L, node, ndef);

// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
try {
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -200,7 +243,12 @@ bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefini
push_item_definition(L, item);

// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
try {
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -217,7 +265,12 @@ bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &poi
push_pointed_thing(L, pointed, true);

// Call functions
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
try {
runCallbacks(2, RUN_CALLBACKS_MODE_OR);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -238,7 +291,12 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory)
lua_rawset(L, -3);
}

runCallbacks(1, RUN_CALLBACKS_MODE_OR);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_OR);
} catch (LuaError &e) {
getClient()->setFatalError(e);
return true;
}
return readParam<bool>(L, -1);
}

@@ -53,13 +53,7 @@ void ScriptApiEnv::environment_Step(float dtime)
lua_getfield(L, -1, "registered_globalsteps");
// Call callbacks
lua_pushnumber(L, dtime);
try {
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getServer()->setAsyncFatalError(
std::string("environment_Step: ") + e.what() + "\n"
+ script_get_backtrace(L));
}
runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
}

void ScriptApiEnv::player_event(ServerActiveObject *player, const std::string &type)
@@ -76,13 +70,7 @@ void ScriptApiEnv::player_event(ServerActiveObject *player, const std::string &t
// Call callbacks
objectrefGetOrCreate(L, player); // player
lua_pushstring(L,type.c_str()); // event type
try {
runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getServer()->setAsyncFatalError(
std::string("player_event: ") + e.what() + "\n"
+ script_get_backtrace(L) );
}
runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}

void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
@@ -257,9 +245,8 @@ void ScriptApiEnv::on_emerge_area_completion(
try {
PCALL_RES(lua_pcall(L, 4, 0, error_handler));
} catch (LuaError &e) {
server->setAsyncFatalError(
std::string("on_emerge_area_completion: ") + e.what() + "\n"
+ script_get_backtrace(L));
// Note: don't throw here, we still need to run the cleanup code below
server->setAsyncFatalError(e);
}

lua_pop(L, 1); // Pop error handler
@@ -300,4 +287,4 @@ void ScriptApiEnv::on_liquid_transformed(
}

runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}
}

0 comments on commit 766e885

Please sign in to comment.