From 3304e1e517fb8aac008c4684e72a4b59b408414a Mon Sep 17 00:00:00 2001
From: Kahrl <kahrl@gmx.net>
Date: Tue, 25 Aug 2015 07:44:53 +0200
Subject: [PATCH] Push error handler afresh each time lua_pcall is used

Fixes "double fault" / "error in error handling" messages
(issue #1423) and instead shows a complete backtrace.
---
 src/script/common/c_internal.cpp   | 14 +++++-----
 src/script/common/c_internal.h     |  4 +++
 src/script/cpp_api/s_async.cpp     | 13 +++++----
 src/script/cpp_api/s_async.h       |  3 +-
 src/script/cpp_api/s_base.cpp      | 30 ++++++++++----------
 src/script/cpp_api/s_base.h        |  2 --
 src/script/cpp_api/s_entity.cpp    | 31 +++++++++++++-------
 src/script/cpp_api/s_inventory.cpp | 33 ++++++++++++++++------
 src/script/cpp_api/s_item.cpp      | 30 +++++++++++++-------
 src/script/cpp_api/s_mainmenu.cpp  | 10 +++++--
 src/script/cpp_api/s_node.cpp      | 45 ++++++++++++++++++++++++------
 src/script/cpp_api/s_nodemeta.cpp  | 33 ++++++++++++++++------
 src/script/cpp_api/s_player.cpp    |  6 ++--
 src/script/cpp_api/s_server.cpp    | 12 ++++++--
 src/script/lua_api/l_env.cpp       | 12 ++++----
 src/script/scripting_mainmenu.cpp  |  2 +-
 16 files changed, 188 insertions(+), 92 deletions(-)

diff --git a/src/script/common/c_internal.cpp b/src/script/common/c_internal.cpp
index 2a10ce0f2..14d992df0 100644
--- a/src/script/common/c_internal.cpp
+++ b/src/script/common/c_internal.cpp
@@ -136,28 +136,28 @@ void script_run_callbacks_f(lua_State *L, int nargs,
 	FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
 
 	// Insert error handler
-	lua_pushcfunction(L, script_error_handler);
-	int errorhandler = lua_gettop(L) - nargs - 1;
-	lua_insert(L, errorhandler);
+	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, errorhandler + 1);
+	lua_insert(L, error_handler + 1);
 
 	// Insert mode after table
 	lua_pushnumber(L, (int) mode);
-	lua_insert(L, errorhandler + 3);
+	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, errorhandler);
+	int result = lua_pcall(L, nargs + 2, 1, error_handler);
 	if (result != 0)
 		script_error(L, result, NULL, fxn);
 
-	lua_remove(L, -2); // Remove error handler
+	lua_remove(L, error_handler);
 }
 
 void log_deprecated(lua_State *L, const std::string &message)
diff --git a/src/script/common/c_internal.h b/src/script/common/c_internal.h
index 80576b5e9..fc59b0e2e 100644
--- a/src/script/common/c_internal.h
+++ b/src/script/common/c_internal.h
@@ -53,7 +53,11 @@ extern "C" {
 #define CUSTOM_RIDX_SCRIPTAPI           (CUSTOM_RIDX_BASE)
 #define CUSTOM_RIDX_GLOBALS_BACKUP      (CUSTOM_RIDX_BASE + 1)
 #define CUSTOM_RIDX_CURRENT_MOD_NAME    (CUSTOM_RIDX_BASE + 2)
+#define CUSTOM_RIDX_ERROR_HANDLER       (CUSTOM_RIDX_BASE + 3)
 
+// Pushes the error handler onto the stack and returns its index
+#define PUSH_ERROR_HANDLER(L) \
+	(lua_rawgeti((L), LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER), lua_gettop((L)))
 
 #define PCALL_RESL(L, RES) do {                         \
 	int result_ = (RES);                                \
diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp
index 1e87e59f0..d18ff6e8c 100644
--- a/src/script/cpp_api/s_async.cpp
+++ b/src/script/cpp_api/s_async.cpp
@@ -144,8 +144,9 @@ void AsyncEngine::putJobResult(LuaJobInfo result)
 }
 
 /******************************************************************************/
-void AsyncEngine::step(lua_State *L, int errorhandler)
+void AsyncEngine::step(lua_State *L)
 {
+	int error_handler = PUSH_ERROR_HANDLER(L);
 	lua_getglobal(L, "core");
 	resultQueueMutex.lock();
 	while (!resultQueue.empty()) {
@@ -164,10 +165,10 @@ void AsyncEngine::step(lua_State *L, int errorhandler)
 		lua_pushlstring(L, jobDone.serializedResult.data(),
 				jobDone.serializedResult.size());
 
-		PCALL_RESL(L, lua_pcall(L, 2, 0, errorhandler));
+		PCALL_RESL(L, lua_pcall(L, 2, 0, error_handler));
 	}
 	resultQueueMutex.unlock();
-	lua_pop(L, 1); // Pop core
+	lua_pop(L, 2); // Pop core and error handler
 }
 
 /******************************************************************************/
@@ -248,6 +249,8 @@ void* AsyncWorkerThread::run()
 		abort();
 	}
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	lua_getglobal(L, "core");
 	if (lua_isnil(L, -1)) {
 		errorstream << "Unable to find core within async environment!";
@@ -279,7 +282,7 @@ void* AsyncWorkerThread::run()
 				toProcess.serializedParams.data(),
 				toProcess.serializedParams.size());
 
-		int result = lua_pcall(L, 2, 1, m_errorhandler);
+		int result = lua_pcall(L, 2, 1, error_handler);
 		if (result) {
 			PCALL_RES(result);
 			toProcess.serializedResult = "";
@@ -296,7 +299,7 @@ void* AsyncWorkerThread::run()
 		jobDispatcher->putJobResult(toProcess);
 	}
 
-	lua_pop(L, 1);  // Pop core
+	lua_pop(L, 2);  // Pop core and error handler
 
 	return 0;
 }
diff --git a/src/script/cpp_api/s_async.h b/src/script/cpp_api/s_async.h
index 7f8c72fae..8d612d58c 100644
--- a/src/script/cpp_api/s_async.h
+++ b/src/script/cpp_api/s_async.h
@@ -95,9 +95,8 @@ class AsyncEngine {
 	 * Engine step to process finished jobs
 	 *   the engine step is one way to pass events back, PushFinishedJobs another
 	 * @param L The Lua stack
-	 * @param errorhandler Stack index of the Lua error handler
 	 */
-	void step(lua_State *L, int errorhandler);
+	void step(lua_State *L);
 
 	/**
 	 * Push a list of finished jobs onto the stack
diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp
index bfe03ec46..78b70e499 100644
--- a/src/script/cpp_api/s_base.cpp
+++ b/src/script/cpp_api/s_base.cpp
@@ -78,14 +78,14 @@ ScriptApiBase::ScriptApiBase()
 
 	luaL_openlibs(m_luastack);
 
-	// Add and save an error handler
-	lua_pushcfunction(m_luastack, script_error_handler);
-	m_errorhandler = lua_gettop(m_luastack);
-
 	// Make the ScriptApiBase* accessible to ModApiBase
 	lua_pushlightuserdata(m_luastack, this);
 	lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_SCRIPTAPI);
 
+	// Add and save an error handler
+	lua_pushcfunction(m_luastack, script_error_handler);
+	lua_rawseti(m_luastack, LUA_REGISTRYINDEX, CUSTOM_RIDX_ERROR_HANDLER);
+
 	// If we are using LuaJIT add a C++ wrapper function to catch
 	// exceptions thrown in Lua -> C++ calls
 #if USE_LUAJIT
@@ -133,13 +133,15 @@ bool ScriptApiBase::loadScript(const std::string &script_path, std::string *erro
 
 	lua_State *L = getStack();
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	bool ok;
 	if (m_secure) {
 		ok = ScriptApiSecurity::safeLoadFile(L, script_path.c_str());
 	} else {
 		ok = !luaL_loadfile(L, script_path.c_str());
 	}
-	ok = ok && !lua_pcall(L, 0, 0, m_errorhandler);
+	ok = ok && !lua_pcall(L, 0, 0, error_handler);
 	if (!ok) {
 		std::string error_msg = lua_tostring(L, -1);
 		if (error)
@@ -150,9 +152,9 @@ bool ScriptApiBase::loadScript(const std::string &script_path, std::string *erro
 			<< error_msg << std::endl << std::endl
 			<< "======= END OF ERROR FROM LUA ========" << std::endl;
 		lua_pop(L, 1); // Pop error message from stack
-		return false;
 	}
-	return true;
+	lua_pop(L, 1); // Pop error handler
+	return ok;
 }
 
 // Push the list of callbacks (a lua table).
@@ -168,28 +170,28 @@ void ScriptApiBase::runCallbacksRaw(int nargs,
 	FATAL_ERROR_IF(lua_gettop(L) < nargs + 1, "Not enough arguments");
 
 	// Insert error handler
-	lua_pushcfunction(L, script_error_handler);
-	int errorhandler = lua_gettop(L) - nargs - 1;
-	lua_insert(L, errorhandler);
+	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, errorhandler + 1);
+	lua_insert(L, error_handler + 1);
 
 	// Insert mode after table
 	lua_pushnumber(L, (int)mode);
-	lua_insert(L, errorhandler + 3);
+	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, errorhandler);
+	int result = lua_pcall(L, nargs + 2, 1, error_handler);
 	if (result != 0)
 		scriptError(result, fxn);
 
-	lua_remove(L, -2); // Remove error handler
+	lua_remove(L, error_handler);
 }
 
 void ScriptApiBase::realityCheck()
diff --git a/src/script/cpp_api/s_base.h b/src/script/cpp_api/s_base.h
index b686d7747..d490f7dfd 100644
--- a/src/script/cpp_api/s_base.h
+++ b/src/script/cpp_api/s_base.h
@@ -109,8 +109,6 @@ class ScriptApiBase {
 
 	Mutex           m_luastackmutex;
 	std::string     m_last_run_mod;
-	// Stack index of Lua error handler
-	int             m_errorhandler;
 	bool            m_secure;
 #ifdef SCRIPTAPI_LOCK_DEBUG
 	bool            m_locked;
diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp
index 0d159846a..378a6bf09 100644
--- a/src/script/cpp_api/s_entity.cpp
+++ b/src/script/cpp_api/s_entity.cpp
@@ -80,6 +80,8 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
 
 	verbosestream << "scriptapi_luaentity_activate: id=" << id << std::endl;
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.luaentities[id]
 	luaentity_get(L, id);
 	int object = lua_gettop(L);
@@ -93,11 +95,11 @@ void ScriptApiEntity::luaentity_Activate(u16 id,
 		lua_pushinteger(L, dtime_s);
 
 		setOriginFromTable(object);
-		PCALL_RES(lua_pcall(L, 3, 0, m_errorhandler));
+		PCALL_RES(lua_pcall(L, 3, 0, error_handler));
 	} else {
 		lua_pop(L, 1);
 	}
-	lua_pop(L, 1); // Pop object
+	lua_pop(L, 2); // Pop object and error handler
 }
 
 void ScriptApiEntity::luaentity_Remove(u16 id)
@@ -126,6 +128,8 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
 
 	//infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.luaentities[id]
 	luaentity_get(L, id);
 	int object = lua_gettop(L);
@@ -140,9 +144,10 @@ std::string ScriptApiEntity::luaentity_GetStaticdata(u16 id)
 	lua_pushvalue(L, object); // self
 
 	setOriginFromTable(object);
-	PCALL_RES(lua_pcall(L, 1, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 1, error_handler));
 
-	lua_remove(L, object); // Remove object
+	lua_remove(L, object);
+	lua_remove(L, error_handler);
 
 	size_t len = 0;
 	const char *s = lua_tolstring(L, -1, &len);
@@ -196,6 +201,8 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
 
 	//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.luaentities[id]
 	luaentity_get(L, id);
 	int object = lua_gettop(L);
@@ -211,9 +218,9 @@ void ScriptApiEntity::luaentity_Step(u16 id, float dtime)
 	lua_pushnumber(L, dtime); // dtime
 
 	setOriginFromTable(object);
-	PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 0, error_handler));
 
-	lua_pop(L, 1); // Pop object
+	lua_pop(L, 2); // Pop object and error handler
 }
 
 // Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
@@ -226,6 +233,8 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
 
 	//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.luaentities[id]
 	luaentity_get(L,id);
 	int object = lua_gettop(L);
@@ -244,9 +253,9 @@ void ScriptApiEntity::luaentity_Punch(u16 id,
 	push_v3f(L, dir);
 
 	setOriginFromTable(object);
-	PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 0, error_handler));
 
-	lua_pop(L, 1); // Pop object
+	lua_pop(L, 2); // Pop object and error handler
 }
 
 // Calls entity:on_rightclick(ObjectRef clicker)
@@ -257,6 +266,8 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
 
 	//infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl;
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.luaentities[id]
 	luaentity_get(L, id);
 	int object = lua_gettop(L);
@@ -272,8 +283,8 @@ void ScriptApiEntity::luaentity_Rightclick(u16 id,
 	objectrefGetOrCreate(L, clicker); // Clicker reference
 
 	setOriginFromTable(object);
-	PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 0, error_handler));
 
-	lua_pop(L, 1); // Pop object
+	lua_pop(L, 2); // Pop object and error handler
 }
 
diff --git a/src/script/cpp_api/s_inventory.cpp b/src/script/cpp_api/s_inventory.cpp
index 019d1ccc0..c90c7d4e2 100644
--- a/src/script/cpp_api/s_inventory.cpp
+++ b/src/script/cpp_api/s_inventory.cpp
@@ -33,6 +33,8 @@ int ScriptApiDetached::detached_inventory_AllowMove(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "allow_move"))
 		return count;
@@ -48,11 +50,11 @@ int ScriptApiDetached::detached_inventory_AllowMove(
 	lua_pushinteger(L, to_index + 1);     // to_index
 	lua_pushinteger(L, count);            // count
 	objectrefGetOrCreate(L, player);      // player
-	PCALL_RES(lua_pcall(L, 7, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 7, 1, error_handler));
 	if(!lua_isnumber(L, -1))
 		throw LuaError("allow_move should return a number. name=" + name);
 	int ret = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return ret;
 }
 
@@ -64,6 +66,8 @@ int ScriptApiDetached::detached_inventory_AllowPut(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "allow_put"))
 		return stack.count; // All will be accepted
@@ -76,11 +80,11 @@ int ScriptApiDetached::detached_inventory_AllowPut(
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 1, error_handler));
 	if (!lua_isnumber(L, -1))
 		throw LuaError("allow_put should return a number. name=" + name);
 	int ret = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return ret;
 }
 
@@ -92,6 +96,8 @@ int ScriptApiDetached::detached_inventory_AllowTake(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "allow_take"))
 		return stack.count; // All will be accepted
@@ -104,11 +110,11 @@ int ScriptApiDetached::detached_inventory_AllowTake(
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 1, error_handler));
 	if (!lua_isnumber(L, -1))
 		throw LuaError("allow_take should return a number. name=" + name);
 	int ret = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return ret;
 }
 
@@ -121,6 +127,8 @@ void ScriptApiDetached::detached_inventory_OnMove(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "on_move"))
 		return;
@@ -136,7 +144,8 @@ void ScriptApiDetached::detached_inventory_OnMove(
 	lua_pushinteger(L, to_index + 1);     // to_index
 	lua_pushinteger(L, count);            // count
 	objectrefGetOrCreate(L, player);      // player
-	PCALL_RES(lua_pcall(L, 7, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 7, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 // Report put items
@@ -147,6 +156,8 @@ void ScriptApiDetached::detached_inventory_OnPut(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "on_put"))
 		return;
@@ -160,7 +171,8 @@ void ScriptApiDetached::detached_inventory_OnPut(
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 // Report taken items
@@ -171,6 +183,8 @@ void ScriptApiDetached::detached_inventory_OnTake(
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getDetachedInventoryCallback(name, "on_take"))
 		return;
@@ -184,7 +198,8 @@ void ScriptApiDetached::detached_inventory_OnTake(
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 // Retrieves core.detached_inventories[name][callbackname]
diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp
index 4d4d416ec..d9a545b4f 100644
--- a/src/script/cpp_api/s_item.cpp
+++ b/src/script/cpp_api/s_item.cpp
@@ -34,6 +34,8 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getItemCallback(item.name.c_str(), "on_drop"))
 		return false;
@@ -42,7 +44,7 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
 	LuaItemStack::create(L, item);
 	objectrefGetOrCreate(L, dropper);
 	pushFloatPos(L, pos);
-	PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 3, 1, error_handler));
 	if (!lua_isnil(L, -1)) {
 		try {
 			item = read_item(L,-1, getServer());
@@ -50,7 +52,7 @@ bool ScriptApiItem::item_OnDrop(ItemStack &item,
 			throw LuaError(std::string(e.what()) + ". item=" + item.name);
 		}
 	}
-	lua_pop(L, 1);  // Pop item
+	lua_pop(L, 2);  // Pop item and error handler
 	return true;
 }
 
@@ -59,6 +61,8 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getItemCallback(item.name.c_str(), "on_place"))
 		return false;
@@ -67,7 +71,7 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
 	LuaItemStack::create(L, item);
 	objectrefGetOrCreate(L, placer);
 	pushPointedThing(pointed);
-	PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 3, 1, error_handler));
 	if (!lua_isnil(L, -1)) {
 		try {
 			item = read_item(L,-1, getServer());
@@ -75,7 +79,7 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item,
 			throw LuaError(std::string(e.what()) + ". item=" + item.name);
 		}
 	}
-	lua_pop(L, 1);  // Pop item
+	lua_pop(L, 2);  // Pop item and error handler
 	return true;
 }
 
@@ -84,6 +88,8 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Push callback function on stack
 	if (!getItemCallback(item.name.c_str(), "on_use"))
 		return false;
@@ -92,7 +98,7 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
 	LuaItemStack::create(L, item);
 	objectrefGetOrCreate(L, user);
 	pushPointedThing(pointed);
-	PCALL_RES(lua_pcall(L, 3, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 3, 1, error_handler));
 	if(!lua_isnil(L, -1)) {
 		try {
 			item = read_item(L,-1, getServer());
@@ -100,7 +106,7 @@ bool ScriptApiItem::item_OnUse(ItemStack &item,
 			throw LuaError(std::string(e.what()) + ". item=" + item.name);
 		}
 	}
-	lua_pop(L, 1);  // Pop item
+	lua_pop(L, 2);  // Pop item and error handler
 	return true;
 }
 
@@ -109,6 +115,8 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	lua_getglobal(L, "core");
 	lua_getfield(L, -1, "on_craft");
 	LuaItemStack::create(L, item);
@@ -122,7 +130,7 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
 	push_items(L, items);
 
 	InvRef::create(L, craft_inv);
-	PCALL_RES(lua_pcall(L, 4, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 4, 1, error_handler));
 	if (!lua_isnil(L, -1)) {
 		try {
 			item = read_item(L,-1, getServer());
@@ -130,7 +138,7 @@ bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
 			throw LuaError(std::string(e.what()) + ". item=" + item.name);
 		}
 	}
-	lua_pop(L, 1);  // Pop item
+	lua_pop(L, 2);  // Pop item and error handler
 	return true;
 }
 
@@ -139,6 +147,8 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	lua_getglobal(L, "core");
 	lua_getfield(L, -1, "craft_predict");
 	LuaItemStack::create(L, item);
@@ -152,7 +162,7 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
 	push_items(L, items);
 
 	InvRef::create(L, craft_inv);
-	PCALL_RES(lua_pcall(L, 4, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 4, 1, error_handler));
 	if (!lua_isnil(L, -1)) {
 		try {
 			item = read_item(L,-1, getServer());
@@ -160,7 +170,7 @@ bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
 			throw LuaError(std::string(e.what()) + ". item=" + item.name);
 		}
 	}
-	lua_pop(L, 1);  // Pop item
+	lua_pop(L, 2);  // Pop item and error handler
 	return true;
 }
 
diff --git a/src/script/cpp_api/s_mainmenu.cpp b/src/script/cpp_api/s_mainmenu.cpp
index 17ceff082..e9a7a13b9 100644
--- a/src/script/cpp_api/s_mainmenu.cpp
+++ b/src/script/cpp_api/s_mainmenu.cpp
@@ -43,6 +43,8 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get handler function
 	lua_getglobal(L, "core");
 	lua_getfield(L, -1, "event_handler");
@@ -55,13 +57,16 @@ void ScriptApiMainMenu::handleMainMenuEvent(std::string text)
 
 	// Call it
 	lua_pushstring(L, text.c_str());
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get handler function
 	lua_getglobal(L, "core");
 	lua_getfield(L, -1, "button_handler");
@@ -84,6 +89,7 @@ void ScriptApiMainMenu::handleMainMenuButtons(const StringMap &fields)
 	}
 
 	// Call it
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp
index dac058b13..f90e65642 100644
--- a/src/script/cpp_api/s_node.cpp
+++ b/src/script/cpp_api/s_node.cpp
@@ -95,6 +95,8 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -106,7 +108,8 @@ bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
 	pushnode(L, node, ndef);
 	objectrefGetOrCreate(L, puncher);
 	pushPointedThing(pointed);
-	PCALL_RES(lua_pcall(L, 4, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 4, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 	return true;
 }
 
@@ -115,6 +118,8 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -125,7 +130,8 @@ bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
 	push_v3s16(L, p);
 	pushnode(L, node, ndef);
 	objectrefGetOrCreate(L, digger);
-	PCALL_RES(lua_pcall(L, 3, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 3, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 	return true;
 }
 
@@ -133,6 +139,8 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -141,13 +149,16 @@ void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
 
 	// Call function
 	push_v3s16(L, p);
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -156,13 +167,16 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
 
 	// Call function
 	push_v3s16(L, p);
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -172,13 +186,16 @@ void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
 	// Call function
 	push_v3s16(L, p);
 	pushnode(L, node, ndef);
-	PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// Push callback function on stack
@@ -188,7 +205,8 @@ bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
 	// Call function
 	push_v3s16(L, p);
 	lua_pushnumber(L,dtime);
-	PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 1, error_handler));
+	lua_remove(L, error_handler);
 	return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
 }
 
@@ -199,6 +217,8 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -223,23 +243,30 @@ void ScriptApiNode::node_on_receive_fields(v3s16 p,
 		lua_settable(L, -3);
 	}
 	objectrefGetOrCreate(L, sender);        // player
-	PCALL_RES(lua_pcall(L, 4, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 4, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 void ScriptApiNode::node_falling_update(v3s16 p)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	lua_getglobal(L, "nodeupdate");
 	push_v3s16(L, p);
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 void ScriptApiNode::node_falling_update_single(v3s16 p)
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	lua_getglobal(L, "nodeupdate_single");
 	push_v3s16(L, p);
-	PCALL_RES(lua_pcall(L, 1, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
diff --git a/src/script/cpp_api/s_nodemeta.cpp b/src/script/cpp_api/s_nodemeta.cpp
index 638750b0e..d050c0bc9 100644
--- a/src/script/cpp_api/s_nodemeta.cpp
+++ b/src/script/cpp_api/s_nodemeta.cpp
@@ -34,6 +34,8 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -54,12 +56,12 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
 	lua_pushinteger(L, to_index + 1);     // to_index
 	lua_pushinteger(L, count);            // count
 	objectrefGetOrCreate(L, player);      // player
-	PCALL_RES(lua_pcall(L, 7, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 7, 1, error_handler));
 	if (!lua_isnumber(L, -1))
 		throw LuaError("allow_metadata_inventory_move should"
 				" return a number, guilty node: " + nodename);
 	int num = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return num;
 }
 
@@ -70,6 +72,8 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -88,12 +92,12 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 1, error_handler));
 	if(!lua_isnumber(L, -1))
 		throw LuaError("allow_metadata_inventory_put should"
 				" return a number, guilty node: " + nodename);
 	int num = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return num;
 }
 
@@ -104,6 +108,8 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -122,12 +128,12 @@ int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 1, error_handler));
 	if (!lua_isnumber(L, -1))
 		throw LuaError("allow_metadata_inventory_take should"
 				" return a number, guilty node: " + nodename);
 	int num = luaL_checkinteger(L, -1);
-	lua_pop(L, 1); // Pop integer
+	lua_pop(L, 2); // Pop integer and error handler
 	return num;
 }
 
@@ -139,6 +145,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -159,7 +167,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
 	lua_pushinteger(L, to_index + 1);     // to_index
 	lua_pushinteger(L, count);            // count
 	objectrefGetOrCreate(L, player);      // player
-	PCALL_RES(lua_pcall(L, 7, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 7, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 // Report put items
@@ -169,6 +178,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -187,7 +198,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 // Report taken items
@@ -197,6 +209,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	INodeDefManager *ndef = getServer()->ndef();
 
 	// If node doesn't exist, we don't know what callback to call
@@ -215,7 +229,8 @@ void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
 	lua_pushinteger(L, index + 1);       // index
 	LuaItemStack::create(L, stack);      // stack
 	objectrefGetOrCreate(L, player);     // player
-	PCALL_RES(lua_pcall(L, 5, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 5, 0, error_handler));
+	lua_pop(L, 1);  // Pop error handler
 }
 
 ScriptApiNodemeta::ScriptApiNodemeta()
diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp
index ef3c31cfd..807430678 100644
--- a/src/script/cpp_api/s_player.cpp
+++ b/src/script/cpp_api/s_player.cpp
@@ -74,6 +74,8 @@ s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
+
 	// Get core.registered_on_player_hpchange
 	lua_getglobal(L, "core");
 	lua_getfield(L, -1, "registered_on_player_hpchange");
@@ -81,9 +83,9 @@ s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
 
 	objectrefGetOrCreate(L, player);
 	lua_pushnumber(L, hp_change);
-	PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 1, error_handler));
 	hp_change = lua_tointeger(L, -1);
-	lua_pop(L, -1);
+	lua_pop(L, 2); // Pop result and error handler
 	return hp_change;
 }
 
diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp
index ec2f9c0af..38bd41f87 100644
--- a/src/script/cpp_api/s_server.cpp
+++ b/src/script/cpp_api/s_server.cpp
@@ -27,13 +27,15 @@ bool ScriptApiServer::getAuth(const std::string &playername,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
 	getAuthHandler();
 	lua_getfield(L, -1, "get_auth");
 	if (lua_type(L, -1) != LUA_TFUNCTION)
 		throw LuaError("Authentication handler missing get_auth");
 	lua_pushstring(L, playername.c_str());
-	PCALL_RES(lua_pcall(L, 1, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 1, 1, error_handler));
 	lua_remove(L, -2); // Remove auth handler
+	lua_remove(L, error_handler);
 
 	// nil = login not allowed
 	if (lua_isnil(L, -1))
@@ -99,6 +101,7 @@ void ScriptApiServer::createAuth(const std::string &playername,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
 	getAuthHandler();
 	lua_getfield(L, -1, "create_auth");
 	lua_remove(L, -2); // Remove auth handler
@@ -106,7 +109,8 @@ void ScriptApiServer::createAuth(const std::string &playername,
 		throw LuaError("Authentication handler missing create_auth");
 	lua_pushstring(L, playername.c_str());
 	lua_pushstring(L, password.c_str());
-	PCALL_RES(lua_pcall(L, 2, 0, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 0, error_handler));
+	lua_pop(L, 1); // Pop error handler
 }
 
 bool ScriptApiServer::setPassword(const std::string &playername,
@@ -114,6 +118,7 @@ bool ScriptApiServer::setPassword(const std::string &playername,
 {
 	SCRIPTAPI_PRECHECKHEADER
 
+	int error_handler = PUSH_ERROR_HANDLER(L);
 	getAuthHandler();
 	lua_getfield(L, -1, "set_password");
 	lua_remove(L, -2); // Remove auth handler
@@ -121,7 +126,8 @@ bool ScriptApiServer::setPassword(const std::string &playername,
 		throw LuaError("Authentication handler missing set_password");
 	lua_pushstring(L, playername.c_str());
 	lua_pushstring(L, password.c_str());
-	PCALL_RES(lua_pcall(L, 2, 1, m_errorhandler));
+	PCALL_RES(lua_pcall(L, 2, 1, error_handler));
+	lua_remove(L, error_handler);
 	return lua_toboolean(L, -1);
 }
 
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 28afdd071..4e0164d90 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -52,8 +52,7 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
 	sanity_check(lua_checkstack(L, 20));
 	StackUnroller stack_unroller(L);
 
-	lua_pushcfunction(L, script_error_handler);
-	int errorhandler = lua_gettop(L);
+	int error_handler = PUSH_ERROR_HANDLER(L);
 
 	// Get registered_abms
 	lua_getglobal(L, "core");
@@ -80,7 +79,7 @@ void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
 	lua_pushnumber(L, active_object_count);
 	lua_pushnumber(L, active_object_count_wider);
 
-	int result = lua_pcall(L, 4, 0, errorhandler);
+	int result = lua_pcall(L, 4, 0, error_handler);
 	if (result)
 		scriptIface->scriptError(result, "LuaABM::trigger");
 
@@ -412,8 +411,7 @@ int ModApiEnvMod::l_add_item(lua_State *L)
 	if(item.empty() || !item.isKnown(getServer(L)->idef()))
 		return 0;
 
-	lua_pushcfunction(L, script_error_handler);
-	int errorhandler = lua_gettop(L);
+	int error_handler = PUSH_ERROR_HANDLER(L);
 
 	// Use spawn_item to spawn a __builtin:item
 	lua_getglobal(L, "core");
@@ -424,9 +422,9 @@ int ModApiEnvMod::l_add_item(lua_State *L)
 	lua_pushvalue(L, 1);
 	lua_pushstring(L, item.getItemString().c_str());
 
-	PCALL_RESL(L, lua_pcall(L, 2, 1, errorhandler));
+	PCALL_RESL(L, lua_pcall(L, 2, 1, error_handler));
 
-	lua_remove(L, errorhandler); // Remove error handler
+	lua_remove(L, error_handler);
 	return 1;
 }
 
diff --git a/src/script/scripting_mainmenu.cpp b/src/script/scripting_mainmenu.cpp
index c74c18edc..b1e50c94b 100644
--- a/src/script/scripting_mainmenu.cpp
+++ b/src/script/scripting_mainmenu.cpp
@@ -78,7 +78,7 @@ void MainMenuScripting::initializeModApi(lua_State *L, int top)
 
 /******************************************************************************/
 void MainMenuScripting::step() {
-	asyncEngine.step(getStack(), m_errorhandler);
+	asyncEngine.step(getStack());
 }
 
 /******************************************************************************/
-- 
GitLab