mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
Add lua exception handling test code
Catch some error situations when mod used without thinking about it
This commit is contained in:
parent
3e267a6ece
commit
e09293b483
106
games/minimal/mods/errorhandler_test/init.lua
Normal file
106
games/minimal/mods/errorhandler_test/init.lua
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
--
|
||||||
|
-- exception handler test module
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- To avoid this from crashing the module will startup in inactive mode.
|
||||||
|
-- to make specific errors happen you need to cause them by following
|
||||||
|
-- chat command:
|
||||||
|
--
|
||||||
|
-- exceptiontest <location> <errortype>
|
||||||
|
--
|
||||||
|
-- location has to be one of:
|
||||||
|
-- * mapgen: cause in next on_generate call
|
||||||
|
-- * entity_step: spawn a entity and make it do error in on_step
|
||||||
|
-- * globalstep: do error in next globalstep
|
||||||
|
-- * immediate: cause right in chat handler
|
||||||
|
--
|
||||||
|
-- errortypes defined are:
|
||||||
|
-- * segv: make sigsegv happen
|
||||||
|
-- * zerodivision: cause a division by zero to happen
|
||||||
|
-- * exception: throw an exception
|
||||||
|
|
||||||
|
if core.cause_error == nil or
|
||||||
|
type(core.cause_error) ~= "function" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
core.log("action", "WARNING: loading exception handler test module!")
|
||||||
|
|
||||||
|
local exceptiondata = {
|
||||||
|
tocause = "none",
|
||||||
|
mapgen = false,
|
||||||
|
entity_step = false,
|
||||||
|
globalstep = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
local exception_entity =
|
||||||
|
{
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
if exceptiondata.entity_step then
|
||||||
|
core.cause_error(exceptiondata.tocause)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
local exception_entity_name = "errorhandler_test:error_entity"
|
||||||
|
|
||||||
|
local function exception_chat_handler(playername, param)
|
||||||
|
local parameters = param:split(" ")
|
||||||
|
|
||||||
|
if #parameters ~= 2 then
|
||||||
|
core.chat_send_player(playername, "Invalid argument count for exceptiontest")
|
||||||
|
end
|
||||||
|
|
||||||
|
core.log("error", "Causing error at:" .. parameters[1])
|
||||||
|
|
||||||
|
if parameters[1] == "mapgen" then
|
||||||
|
exceptiondata.tocause = parameters[2]
|
||||||
|
exceptiondata.mapgen = true
|
||||||
|
elseif parameters[1] == "entity_step" then
|
||||||
|
--spawn entity at player location
|
||||||
|
local player = core.get_player_by_name(playername)
|
||||||
|
|
||||||
|
if player:is_player() then
|
||||||
|
local pos = player:getpos()
|
||||||
|
|
||||||
|
core.add_entity(pos, exception_entity_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
exceptiondata.tocause = parameters[2]
|
||||||
|
exceptiondata.entity_step = true
|
||||||
|
|
||||||
|
elseif parameters[1] == "globalstep" then
|
||||||
|
exceptiondata.tocause = parameters[2]
|
||||||
|
exceptiondata.globalstep = true
|
||||||
|
|
||||||
|
elseif parameters[1] == "immediate" then
|
||||||
|
core.cause_error(parameters[2])
|
||||||
|
|
||||||
|
else
|
||||||
|
core.chat_send_player(playername, "Invalid error location: " .. dump(parameters[1]))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.register_chatcommand("exceptiontest",
|
||||||
|
{
|
||||||
|
params = "<location> <errortype>",
|
||||||
|
description = "cause a given error to happen.\n" ..
|
||||||
|
" location=(mapgen,entity_step,globalstep,immediate)\n" ..
|
||||||
|
" errortype=(segv,zerodivision,exception)",
|
||||||
|
func = exception_chat_handler,
|
||||||
|
privs = { server=true }
|
||||||
|
})
|
||||||
|
|
||||||
|
core.register_globalstep(function(dtime)
|
||||||
|
if exceptiondata.globalstep then
|
||||||
|
core.cause_error(exceptiondata.tocause)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
core.register_on_generated(function(minp, maxp, blockseed)
|
||||||
|
if exceptiondata.mapgen then
|
||||||
|
core.cause_error(exceptiondata.tocause)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
core.register_entity(exception_entity_name, exception_entity)
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
// request_shutdown()
|
// request_shutdown()
|
||||||
int ModApiServer::l_request_shutdown(lua_State *L)
|
int ModApiServer::l_request_shutdown(lua_State *L)
|
||||||
@ -449,6 +450,36 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// cause_error(type_of_error)
|
||||||
|
int ModApiServer::l_cause_error(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
std::string type_of_error = "none";
|
||||||
|
if(lua_isstring(L, 1))
|
||||||
|
type_of_error = lua_tostring(L, 1);
|
||||||
|
|
||||||
|
errorstream << "Error handler test called, errortype=" << type_of_error << std::endl;
|
||||||
|
|
||||||
|
if(type_of_error == "segv") {
|
||||||
|
volatile int* some_pointer = 0;
|
||||||
|
errorstream << "Cause a sigsegv now: " << (*some_pointer) << std::endl;
|
||||||
|
|
||||||
|
} else if (type_of_error == "zerodivision") {
|
||||||
|
|
||||||
|
unsigned int some_number = porting::getTimeS();
|
||||||
|
unsigned int zerovalue = 0;
|
||||||
|
unsigned int result = some_number / zerovalue;
|
||||||
|
errorstream << "Well this shouldn't ever be shown: " << result << std::endl;
|
||||||
|
|
||||||
|
} else if (type_of_error == "exception") {
|
||||||
|
throw BaseException("Errorhandler test fct called");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void ModApiServer::Initialize(lua_State *L, int top)
|
void ModApiServer::Initialize(lua_State *L, int top)
|
||||||
{
|
{
|
||||||
API_FCT(request_shutdown);
|
API_FCT(request_shutdown);
|
||||||
@ -475,4 +506,8 @@ void ModApiServer::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(kick_player);
|
API_FCT(kick_player);
|
||||||
API_FCT(unban_player_or_ip);
|
API_FCT(unban_player_or_ip);
|
||||||
API_FCT(notify_authentication_modified);
|
API_FCT(notify_authentication_modified);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
API_FCT(cause_error);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,11 @@ private:
|
|||||||
// notify_authentication_modified(name)
|
// notify_authentication_modified(name)
|
||||||
static int l_notify_authentication_modified(lua_State *L);
|
static int l_notify_authentication_modified(lua_State *L);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// cause_error(type_of_error)
|
||||||
|
static int l_cause_error(lua_State *L);
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Initialize(lua_State *L, int top);
|
static void Initialize(lua_State *L, int top);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user