Skip to content
Permalink
Browse files

Add lua exception handling test code

Catch some error situations when mod used without thinking about it
  • Loading branch information...
sapier sapier
sapier authored and sapier committed Aug 23, 2014
1 parent 3e267a6 commit e09293b483fcfb5a2095d4bfeccae57153df6250
Showing with 146 additions and 0 deletions.
  1. +106 −0 games/minimal/mods/errorhandler_test/init.lua
  2. +35 −0 src/script/lua_api/l_server.cpp
  3. +5 −0 src/script/lua_api/l_server.h
@@ -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 "environment.h"
#include "player.h"
#include "log.h"

// request_shutdown()
int ModApiServer::l_request_shutdown(lua_State *L)
@@ -449,6 +450,36 @@ int ModApiServer::l_notify_authentication_modified(lua_State *L)
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)
{
API_FCT(request_shutdown);
@@ -475,4 +506,8 @@ void ModApiServer::Initialize(lua_State *L, int top)
API_FCT(kick_player);
API_FCT(unban_player_or_ip);
API_FCT(notify_authentication_modified);

#ifndef NDEBUG
API_FCT(cause_error);
#endif
}
@@ -88,6 +88,11 @@ class ModApiServer : public ModApiBase {
// notify_authentication_modified(name)
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:
static void Initialize(lua_State *L, int top);

0 comments on commit e09293b

Please sign in to comment.
You can’t perform that action at this time.