Improved error handling in the command system

This commit is contained in:
red-agent 2009-09-12 23:22:50 +03:00
parent ae0f32d922
commit 981572f79d
2 changed files with 31 additions and 22 deletions

View File

@ -25,6 +25,20 @@ from inspect import getargspec
class CommandInternalError(Exception):
pass
class CommandError(Exception):
def __init__(self, message=None, command=None, name=None):
if command:
self.command = command
self.name = command.first_name
elif name:
self.command = None
self.name = name
if message:
super(CommandError, self).__init__(message)
else:
super(CommandError, self).__init__()
class Command(object):
DOC_STRIP_PATTERN = re.compile(r'(?:^[ \t]+|\A\n)', re.MULTILINE)
@ -43,7 +57,13 @@ class Command(object):
self.empty = empty
def __call__(self, *args, **kwargs):
return self.handler(*args, **kwargs)
try:
return self.handler(*args, **kwargs)
except CommandError, exception:
if not exception.command and not exception.name:
raise CommandError(exception.message, self)
except TypeError:
raise CommandError("Command received invalid arguments", self)
def __repr__(self):
return "<Command %s>" % ', '.join(self.names)
@ -56,7 +76,7 @@ class Command(object):
@property
def first_name(self):
return self.names[0]
return self.names[0]
@property
def native_name(self):
@ -162,14 +182,6 @@ class Command(object):
return usage if not complete else self.ARG_USAGE_PATTERN % (names, usage)
class CommandError(Exception):
def __init__(self, command, *args, **kwargs):
if isinstance(command, Command):
self.command = command
self.name = command.first_name
self.name = command
super(Exception, self).__init__(*args, **kwargs)
class Dispatcher(type):
table = {}
hosted = {}
@ -180,7 +192,7 @@ class Dispatcher(type):
if Dispatcher.is_suitable(cls, dct):
Dispatcher.register_processor(cls)
# Sanitize names even if processor is not suitable for registering,
# because it might be inherited by an another processor.
Dispatcher.sanitize_names(cls)
@ -226,7 +238,7 @@ class Dispatcher(type):
if 'HOSTED_BY' in proc.__dict__:
cls.register_adhocs(proc)
commands = cls.traverse_commands(proc, inherited)
cls.register_commands(proc, commands)
@ -362,7 +374,7 @@ class CommandProcessor(object):
name = cls.prepare_name(name)
command = Dispatcher.retrieve_command(cls, name)
if not command:
raise CommandError(name, "Command does not exist")
raise CommandError("Command does not exist", name=name)
return command
@classmethod
@ -446,7 +458,7 @@ class CommandProcessor(object):
if len(spec_args) == 1:
if arguments or command.empty:
return (arguments,), {}
raise CommandError(command, "Can not be used without arguments")
raise CommandError("Can not be used without arguments", command)
raise CommandInternalError("Raw command must define no more then one argument")
if '__optional__' in spec_args:
@ -520,13 +532,10 @@ class CommandProcessor(object):
args, kwargs = self.parse_command_arguments(arguments) if arguments else ([], {})
args, kwargs = self.adapt_command_arguments(command, arguments, args, kwargs)
try:
if self.command_preprocessor(name, command, arguments, args, kwargs):
return
value = command(self, *args, **kwargs)
self.command_postprocessor(name, command, arguments, args, kwargs, value)
except TypeError:
raise CommandError(name, "Command received invalid arguments")
if self.command_preprocessor(name, command, arguments, args, kwargs):
return
value = command(self, *args, **kwargs)
self.command_postprocessor(name, command, arguments, args, kwargs, value)
def command_preprocessor(self, name, command, arguments, args, kwargs):
"""

View File

@ -100,7 +100,7 @@ class ChatCommands(CommonCommands):
Send a ping to the contact
"""
if self.account == gajim.ZEROCONF_ACC_NAME:
raise CommandError(ping, _('Command is not supported for zeroconf accounts'))
raise CommandError(_('Command is not supported for zeroconf accounts'))
gajim.connections[self.account].sendPing(self.contact)
class PrivateChatCommands(CommonCommands):