Improved error handling in the command system
This commit is contained in:
		
							parent
							
								
									ae0f32d922
								
							
						
					
					
						commit
						981572f79d
					
				
					 2 changed files with 31 additions and 22 deletions
				
			
		|  | @ -25,6 +25,20 @@ from inspect import getargspec | ||||||
| class CommandInternalError(Exception): | class CommandInternalError(Exception): | ||||||
|     pass |     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): | class Command(object): | ||||||
| 
 | 
 | ||||||
|     DOC_STRIP_PATTERN = re.compile(r'(?:^[ \t]+|\A\n)', re.MULTILINE) |     DOC_STRIP_PATTERN = re.compile(r'(?:^[ \t]+|\A\n)', re.MULTILINE) | ||||||
|  | @ -43,7 +57,13 @@ class Command(object): | ||||||
|         self.empty = empty |         self.empty = empty | ||||||
| 
 | 
 | ||||||
|     def __call__(self, *args, **kwargs): |     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): |     def __repr__(self): | ||||||
|         return "<Command %s>" % ', '.join(self.names) |         return "<Command %s>" % ', '.join(self.names) | ||||||
|  | @ -162,14 +182,6 @@ class Command(object): | ||||||
| 
 | 
 | ||||||
|         return usage if not complete else self.ARG_USAGE_PATTERN % (names, usage) |         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): | class Dispatcher(type): | ||||||
|     table = {} |     table = {} | ||||||
|     hosted = {} |     hosted = {} | ||||||
|  | @ -362,7 +374,7 @@ class CommandProcessor(object): | ||||||
|         name = cls.prepare_name(name) |         name = cls.prepare_name(name) | ||||||
|         command = Dispatcher.retrieve_command(cls, name) |         command = Dispatcher.retrieve_command(cls, name) | ||||||
|         if not command: |         if not command: | ||||||
|             raise CommandError(name, "Command does not exist") |             raise CommandError("Command does not exist", name=name) | ||||||
|         return command |         return command | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|  | @ -446,7 +458,7 @@ class CommandProcessor(object): | ||||||
|             if len(spec_args) == 1: |             if len(spec_args) == 1: | ||||||
|                 if arguments or command.empty: |                 if arguments or command.empty: | ||||||
|                     return (arguments,), {} |                     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") |             raise CommandInternalError("Raw command must define no more then one argument") | ||||||
| 
 | 
 | ||||||
|         if '__optional__' in spec_args: |         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.parse_command_arguments(arguments) if arguments else ([], {}) | ||||||
|         args, kwargs = self.adapt_command_arguments(command, arguments, args, kwargs) |         args, kwargs = self.adapt_command_arguments(command, arguments, args, kwargs) | ||||||
| 
 | 
 | ||||||
|         try: |         if self.command_preprocessor(name, command, arguments, args, kwargs): | ||||||
|             if self.command_preprocessor(name, command, arguments, args, kwargs): |             return | ||||||
|                 return |         value = command(self, *args, **kwargs) | ||||||
|             value = command(self, *args, **kwargs) |         self.command_postprocessor(name, command, arguments, args, kwargs, value) | ||||||
|             self.command_postprocessor(name, command, arguments, args, kwargs, value) |  | ||||||
|         except TypeError: |  | ||||||
|            raise CommandError(name, "Command received invalid arguments") |  | ||||||
| 
 | 
 | ||||||
|     def command_preprocessor(self, name, command, arguments, args, kwargs): |     def command_preprocessor(self, name, command, arguments, args, kwargs): | ||||||
|         """ |         """ | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ class ChatCommands(CommonCommands): | ||||||
|         Send a ping to the contact |         Send a ping to the contact | ||||||
|         """ |         """ | ||||||
|         if self.account == gajim.ZEROCONF_ACC_NAME: |         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) |         gajim.connections[self.account].sendPing(self.contact) | ||||||
| 
 | 
 | ||||||
| class PrivateChatCommands(CommonCommands): | class PrivateChatCommands(CommonCommands): | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue