From: Alfredo Deza Date: Fri, 9 Aug 2013 22:38:48 +0000 (-0700) Subject: create a catches decorator to handle exceptions X-Git-Tag: v1.2~4^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dd1b5446566d7eb3897f995c043b06d1ac7dce9b;p=ceph-deploy.git create a catches decorator to handle exceptions Signed-off-by: Alfredo Deza --- diff --git a/ceph_deploy/util/decorators.py b/ceph_deploy/util/decorators.py index fee16c9..977ccff 100644 --- a/ceph_deploy/util/decorators.py +++ b/ceph_deploy/util/decorators.py @@ -1,3 +1,6 @@ +import logging +import sys +from functools import wraps def remote_compile(client, fn): @@ -19,3 +22,73 @@ def remote_compile(client, fn): raise RemoteException(remote_trace.split('\n'), err) return inner return client.compile(outer)(client.compile(fn)) + + +def catches(catch=None, handler=None, exit=True): + """ + Very simple decorator that tries any of the exception(s) passed in as + a single exception class or tuple (containing multiple ones) returning the + exception message and optionally handling the problem if it rises with the + handler if it is provided. + + So instead of douing something like this:: + + def bar(): + try: + some_call() + print "Success!" + except TypeError, exc: + print "Error while handling some call: %s" % exc + sys.exit(1) + + You would need to decorate it like this to have the same effect:: + + @catches(TypeError) + def bar(): + some_call() + print "Success!" + + If multiple exceptions need to be caught they need to be provided as a + tuple:: + + @catches((TypeError, AttributeError)) + def bar(): + some_call() + print "Success!" + """ + catch = catch or Exception + logger = logging.getLogger('ceph_deploy') + + def decorate(f): + + @wraps(f) + def newfunc(*a, **kw): + try: + return f(*a, **kw) + except catch as e: + if handler: + return handler(e) + else: + logger.error(make_exception_message(e)) + if exit: + sys.exit(1) + return newfunc + + return decorate + +# +# Decorator helpers +# + + +def make_exception_message(exc): + """ + An exception is passed in and this function + returns the proper string depending on the result + so it is readable enough. + """ + if str(exc): + return '%s: %s\n' % (exc.__class__.__name__, exc) + else: + return '%s\n' % (exc.__class__.__name__) +