fix exception handling
authorAlexander Solovyov <alexander@solovyov.net>
Thu, 18 Nov 2010 22:15:57 +0100
changeset 136 57444e973879
parent 135 444518c54a66
child 137 3b2fcbad96d7
fix exception handling
opster.py
tests/multicommands.py
tests/opster.t
--- a/opster.py	Mon Nov 15 14:56:57 2010 +0100
+++ b/opster.py	Thu Nov 18 22:15:57 2010 +0100
@@ -87,12 +87,19 @@
                 # no catcher here because this is call from Python
                 return call_cmd_regular(func, options_)(*args, **opts)
 
-            opts, args = catcher(lambda: parse(argv, options_), help_func)
+            try:
+                opts, args = catcher(lambda: parse(argv, options_), help_func)
+            except Abort:
+                return -1
 
             if opts.pop('help', False):
                 return help_func()
-            return catcher(lambda: call_cmd(name_, func)(*args, **opts),
-                           help_func)
+
+            try:
+                return catcher(lambda: call_cmd(name_, func)(*args, **opts),
+                               help_func)
+            except Abort:
+                return -1
 
         return inner
     return wrapper
@@ -132,17 +139,22 @@
 
     autocomplete(cmdtable, args, middleware)
 
-    name, func, args, kwargs = catcher(
-        lambda: _dispatch(args, cmdtable, globaloptions),
-        help_func)
+    try:
+        name, func, args, kwargs = catcher(
+            lambda: _dispatch(args, cmdtable, globaloptions),
+            help_func)
+    except Abort:
+        return -1
+
     if name == '_completion':       # skip middleware
-        return catcher(
-            lambda: call_cmd(name, func)(*args, **kwargs),
-            help_func)
+        worker = lambda: call_cmd(name, func)(*args, **kwargs)
     else:
-        return catcher(
-            lambda: call_cmd(name, middleware(func))(*args, **kwargs),
-            help_func)
+        worker = lambda: call_cmd(name, middleware(func))(*args, **kwargs)
+
+    try:
+        return catcher(worker, help_func)
+    except Abort:
+        return -1
 
 # --------
 # Help
@@ -451,17 +463,22 @@
         return target()
     except UnknownCommand, e:
         err("unknown command: '%s'\n" % e)
+        raise Abort()
     except AmbiguousCommand, e:
         err("command '%s' is ambiguous:\n    %s\n" %
             (e.args[0], ' '.join(e.args[1])))
+        raise Abort()
     except ParseError, e:
         err('%s: %s\n' % (e.args[0], e.args[1]))
         help_func(e.args[0])
+        raise Abort()
     except getopt.GetoptError, e:
         err('error: %s\n' % e)
         help_func()
+        raise Abort()
     except OpsterError, e:
         err('%s\n' % e)
+        raise Abort()
 
 def call_cmd(name, func):
     def inner(*args, **kwargs):
@@ -603,17 +620,17 @@
 # --------
 
 # Command exceptions
-class CommandException(Exception):
-    'Base class for command exceptions'
+class OpsterError(Exception):
+    'Base opster exception'
 
-class AmbiguousCommand(CommandException):
+class AmbiguousCommand(OpsterError):
     'Raised if command is ambiguous'
 
-class UnknownCommand(CommandException):
+class UnknownCommand(OpsterError):
     'Raised if command is unknown'
 
-class ParseError(CommandException):
+class ParseError(OpsterError):
     'Raised on error in command line parsing'
 
-class OpsterError(CommandException):
-    'Raised on trouble with opster configuration'
+class Abort(OpsterError):
+    'Processing error, abort execution'
--- a/tests/multicommands.py	Mon Nov 15 14:56:57 2010 +0100
+++ b/tests/multicommands.py	Thu Nov 18 22:15:57 2010 +0100
@@ -22,7 +22,7 @@
 
 @command(cplx_opts, usage='[-p] [--exit value] ...', name='complex', hide=True)
 def complex_(ui, *args, **opts):
-    u'''That's more complex command indented to do something
+    u'''That's more complex command intended to do something
 
     И самое главное - мы тут немножечко текста не в ascii напишем
     и посмотрим, что будет. :)
--- a/tests/opster.t	Mon Nov 15 14:56:57 2010 +0100
+++ b/tests/opster.t	Thu Nov 18 22:15:57 2010 +0100
@@ -25,7 +25,7 @@
   $ run multicommands.py help complex
   /Users/piranha/dev/misc/opster/tests/multicommands.py complex [-p] [--exit value] ...
   
-  That's more complex command indented to do something
+  That's more complex command intended to do something
   
       И самое главное - мы тут немножечко текста не в ascii напишем
       и посмотрим, что будет. :)
@@ -67,4 +67,21 @@
    'port': 8000,
    'test': 'test'}
 
+Should we check passing some invalid arguments? I think so::
+
+  $ run test_opts.py --wrong-option
+  error: option --wrong-option not recognized
+  /Users/piranha/dev/misc/opster/tests/test_opts.py [-l HOST] DIR
+  
+  Command with option declaration as keyword arguments
+  
+  options:
+  
+   -l --listen     ip to listen on (default: localhost)
+   -p --port       port to listen on (default: 8000)
+   -d --daemonize  daemonize process
+      --pid-file   name of file to write process ID to
+   -t --test       testing help for a function (default: test)
+   -h --help       show help
+
 That's all for today; see you next time!