Python - 将异常捕获视为通用函数的简单方法

时间:2017-01-14 20:49:58

标签: python exception try-catch

我们说我有以下代码,另外还有10个代码。

try:
   session.get('http://www.google.com')
except rex.MissingSchema as e:
    raise RESTClientException('Bad URL for request: ' + str(url), 'error:url', e)
except rex.ConnectionError as e:
    raise RESTClientException('Cannot connect for token', 'error:connection', e)
except rfcex.InsecureTransportError as e:
    raise RESTClientException('Verify certificates True without https', 'error:https', e)

让我们说我想在多个功能中使用所有这些,除了它们,它们究竟是怎样的。我能想到的唯一方法就是:

try:
    session.get('http://www.google.com')
except Exception as e:
    interpret_exception(e)

def interpret_exception(e)
    if isinstance(e, rex.MissingSchema):
        raise RESTClientException('Bad URL for request: ' + str(url), 'error:url', e)
    elif isinstance(e, rex.ConnectionError):
        raise RESTClientException('Cannot connect for token', 'error:connection', e)
    #etc...

有更好的方法吗? 感谢

1 个答案:

答案 0 :(得分:1)

我使用装饰器将某些类型的已知异常(可能在函数中发生)包装到另一个异常类型中。目标是为客户端代码提供一个除之外的的异常类型。 这可能会帮助您优雅地为每个函数重新提升RESTClientException,如果这是您主要追求的。但是它不会转换任何错误消息。 (也许这对你来说更重要,因为原始信息不够清晰!?)

def wrap_known_exceptions(exceptions_to_wrap, exception_to_raise):
"""Wrap a tuple of known exceptions into another exception to offer client
code a single error to try/except against.

Args:
    exceptions_to_wrap (instance or tuple): Tuple of exception types that
        are caught when arising and wrapped.
    exception_to_raise (Exception type): Exception that will be raised on
        an occurence of an exception from ``exceptions_to_wrap``.

Raises:
    exception_to_raise's type.
"""
def closure(func):

    @wraps(func)
    def wrapped_func(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except exceptions_to_wrap as exception_instance:
            msg = u"wraps {0}: {1}"
            msg = msg.format(type(exception_instance).__name__, exception_instance)
            raise exception_to_raise(msg)

    return wrapped_func
return closure

以下是它的使用方法:

class RESTClientException(Exception):
    """RESTClientException"""

@wrap_known_exceptions(ValueError, RESTClientException)  # could also be a tuple
def test():
    raise ValueError("Problem occured")

test()

输出:

Traceback (most recent call last):
  File "C:/symlinks/..../utilities/decorators.py", line 69, in <module>
    test()
  File "C:/symlinks/..../utilities/decorators.py", line 32, in wrapped_func
    raise exception_to_raise(msg)
__main__.RESTClientException: wraps ValueError: Problem occured