Extended cmdhandler error reporting with a lot - every inlineCallback needs its own internal error reporting in order to catch everything.

This commit is contained in:
Griatch 2015-02-22 15:21:31 +01:00
parent c1243a9d6d
commit d1cd9da6bf
2 changed files with 188 additions and 142 deletions

View file

@ -71,8 +71,39 @@ CMD_CHANNEL = "__send_to_channel_command"
# (is expected to display the login screen) # (is expected to display the login screen)
CMD_LOGINSTART = "__unloggedin_look_command" CMD_LOGINSTART = "__unloggedin_look_command"
# custom Exceptions # Output strings
_ERROR_UNTRAPPED = "{traceback}\n" \
"Above traceback is from an untrapped error. " \
"Please file a bug report."
_ERROR_CMDSETS = "{traceback}\n" \
"Above traceback is from a cmdset merger error. " \
"Please file a bug report."
_ERROR_NOCMDSETS = "No command sets found! This is a sign of a critical bug." \
"\nThe error was logged. If disconnecting/reconnecting doesn't" \
"\nsolve the problem, try to contact the server admin through" \
"\nsome other means for assistance."
_ERROR_CMDHANDLER = "{traceback}\n"\
"Above traceback is from a Command handler bug." \
"Please file a bug report with the Evennia project."
def _msg_err(receiver, string):
"""
Helper function for returning an error to the caller.
Args:
receiver (Object): object to get the error message
string (str): string with a {traceback} format marker inside it.
"""
receiver.msg(string.format(traceback=format_exc()))
# custom Exceptions
class NoCmdSets(Exception): class NoCmdSets(Exception):
"No cmdsets found. Critical error." "No cmdsets found. Critical error."
@ -86,8 +117,10 @@ class ExecSystemCommand(Exception):
self.syscmd = syscmd self.syscmd = syscmd
self.sysarg = sysarg self.sysarg = sysarg
# Helper function class ErrorReported(Exception):
"Re-raised when a subsructure already reported the error"
# Helper function
@inlineCallbacks @inlineCallbacks
def get_and_merge_cmdsets(caller, session, player, obj, def get_and_merge_cmdsets(caller, session, player, obj,
@ -107,21 +140,28 @@ def get_and_merge_cmdsets(caller, session, player, obj,
Note that this function returns a deferred! Note that this function returns a deferred!
""" """
try:
local_obj_cmdsets = [None] local_obj_cmdsets = [None]
@inlineCallbacks @inlineCallbacks
def _get_channel_cmdsets(player, player_cmdset): def _get_channel_cmdsets(player, player_cmdset):
"Channel-cmdsets" "Channel-cmdsets"
# Create cmdset for all player's available channels # Create cmdset for all player's available channels
try:
channel_cmdset = None channel_cmdset = None
if not player_cmdset.no_channels: if not player_cmdset.no_channels:
channel_cmdset = yield CHANNELHANDLER.get_cmdset(player) channel_cmdset = yield CHANNELHANDLER.get_cmdset(player)
returnValue(channel_cmdset) returnValue(channel_cmdset)
except Exception:
logger.log_trace()
_msg_err(caller, _ERROR_CMDSETS)
raise ErrorReported
@inlineCallbacks @inlineCallbacks
def _get_local_obj_cmdsets(obj, obj_cmdset): def _get_local_obj_cmdsets(obj, obj_cmdset):
"Object-level cmdsets" "Object-level cmdsets"
# Gather cmdsets from location, objects in location or carried # Gather cmdsets from location, objects in location or carried
try:
local_obj_cmdsets = [None] local_obj_cmdsets = [None]
try: try:
location = obj.location location = obj.location
@ -152,6 +192,11 @@ def get_and_merge_cmdsets(caller, session, player, obj,
cset.old_duplicates = cset.duplicates cset.old_duplicates = cset.duplicates
cset.duplicates = True cset.duplicates = True
returnValue(local_obj_cmdsets) returnValue(local_obj_cmdsets)
except Exception:
logger.log_trace()
_msg_err(caller, _ERROR_CMDSETS)
raise ErrorReported
@inlineCallbacks @inlineCallbacks
def _get_cmdset(obj): def _get_cmdset(obj):
@ -246,7 +291,12 @@ def get_and_merge_cmdsets(caller, session, player, obj,
cset.duplicates = cset.old_duplicates cset.duplicates = cset.old_duplicates
#print "merged set:", cmdset.key #print "merged set:", cmdset.key
returnValue(cmdset) returnValue(cmdset)
except ErrorReported:
raise
except Exception:
logger.log_trace()
_msg_err(caller, _ERROR_CMDSETS)
raise ErrorReported
# Main command-handler function # Main command-handler function
@ -344,10 +394,9 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
returnValue(ret) returnValue(ret)
except Exception: except Exception:
string = "%s\nAbove traceback is from an untrapped error." logger.log_trace()
string += " Please file a bug report." _msg_err(caller, _ERROR_UNTRAPPED)
logger.log_trace(_(string)) raise ErrorReported
caller.msg(string % format_exc())
raw_string = to_unicode(raw_string, force_string=True) raw_string = to_unicode(raw_string, force_string=True)
@ -449,6 +498,11 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
ret = yield _run_command(cmd, cmdname, args) ret = yield _run_command(cmd, cmdname, args)
returnValue(ret) returnValue(ret)
except ErrorReported:
# this error was already reported, so we
# catch it here and don't pass it on.
pass
except ExecSystemCommand, exc: except ExecSystemCommand, exc:
# Not a normal command: run a system command, if available, # Not a normal command: run a system command, if available,
# or fall back to a return string. # or fall back to a return string.
@ -464,24 +518,15 @@ def cmdhandler(called_by, raw_string, _testing=False, callertype="session", sess
except NoCmdSets: except NoCmdSets:
# Critical error. # Critical error.
string = "No command sets found! This is a sign of a critical bug.\n"
string += "The error was logged.\n"
string += "If logging out/in doesn't solve the problem, try to "
string += "contact the server admin through some other means "
string += "for assistance."
caller.msg(_(string))
logger.log_errmsg("No cmdsets found: %s" % caller) logger.log_errmsg("No cmdsets found: %s" % caller)
caller.msg(_ERROR_NOCMDSETS)
except Exception: except Exception:
# We should not end up here. If we do, it's a programming bug. # We should not end up here. If we do, it's a programming bug.
string = "%s\nAbove traceback is from an untrapped error." logger.log_trace()
string += " Please file a bug report." _msg_err(caller, _ERROR_UNTRAPPED)
logger.log_trace(_(string))
caller.msg(string % format_exc())
except Exception: except Exception:
# This catches exceptions in cmdhandler exceptions themselves # This catches exceptions in cmdhandler exceptions themselves
string = "%s\nAbove traceback is from a Command handler bug." logger.log_trace()
string += " Please contact an admin and/or file a bug report." _msg_err(caller, _ERROR_CMDHANDLER)
logger.log_trace(_(string))
caller.msg(string % format_exc())

View file

@ -184,6 +184,7 @@ class Mob(tut_objects.TutorialObject):
if last_interval: if last_interval:
# we have a previous subscription, kill this first. # we have a previous subscription, kill this first.
TICKER_HANDLER.remove(self, last_interval, idstring) TICKER_HANDLER.remove(self, last_interval, idstring)
self.db.last_ticker_interval = interval
if not stop: if not stop:
# set the new ticker # set the new ticker
TICKER_HANDLER.add(self, interval, idstring, hook_key) TICKER_HANDLER.add(self, interval, idstring, hook_key)