【问题标题】:How do I rethrow an exception that contains information about an original exception?如何重新引发包含有关原始异常的信息的异常?
【发布时间】:2012-05-20 07:18:50
【问题描述】:

所以我基本上必须通过异常将应用程序的 2 层相互隔离。

我有这个 WLST 12c 脚本(python 2.2),就像

try:
    something something...
except java.lang.UnsuportedOpperationException, (a, b):
    pass
except java.lang.reflect.UndeclaredThrowableException, (a, b):
    pass

我希望能够重新引发我自己的一种异常类型,其中包含有关导致上一个异常的原因的消息(不,我不知道 ab 是什么参数是,但我猜其中一个应该是异常描述)。

我自己是一个java人,所以我很期待类似的东西

try {
    something something...
} catch (Exception e) {
    throw new RuntimeException(e, "something horrible happened");
}

【问题讨论】:

  • 你到底为什么使用python 2.2?最新的 2.2 版本是 2003 年。据我所知,目前还没有发行版为其当前版本提供该版本...
  • 实际上看起来像是在使用 Jython 解释器,就版本号而言,它可能落后于 CPython

标签: python exception-handling wlst python-2.2


【解决方案1】:

在 Python 3 中,raise from 构造完全符合您的要求。它引发了新异常,将原始异常保存在新异常的__cause__ 属性中。

请看这里:https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

【讨论】:

    【解决方案2】:

    成语

    try:
       ...
    except SomeException:
       ...
       raise
    

    @normaldotcom 提到的重新抛出已按原样捕获的错误,无需任何修改。它确实回答 OP,“我如何创建一个包含有关已捕获异常的信息的新异常”。

    确实,在某些情况下,人们希望创建一个新异常,通常是将许多可能的内部错误来源重新组合成一个带有更清晰消息的异常,同时仍保留对原始错误的回溯以启用调试。

    实现此目的的一种方法是通过with_traceback method of BaseException。例如,

    import sys
    
    try:
      raise ValueError('internal error message')
    except ValueError:
      tb = sys.exc_info()[2]
      raise Exception('new error message').with_traceback(tb)
    

    【讨论】:

      【解决方案3】:

      虽然这是一篇旧帖子,但对原始问题有一个更简单的答案。要在捕获异常后重新抛出异常,只需使用不带参数的“raise”。原始堆栈跟踪将被保留。

      【讨论】:

        【解决方案4】:
        class MyException(Exception): pass
        
        ...
        
        try:
            my_funcion(my_args)
        except (IOError, KeyError, some_list_of_other_possible_exceptions), e:
            raise MyException("Uh oh")
        

        您可以从这里绑定到 e 的原始异常中提取信息,然后在引发它时将其传递给您自己的异常。

        【讨论】:

        • 请注意,multicatch 必须是指定类型的最后一个 except 语句
        【解决方案5】:

        我希望我的问题是正确的。

        我不确定 Python 2.2 的细节,但 this 说您可以像在最近的版本中一样处理异常:

        try:
            do_stuff()
        except ErrorToCatch, e:
            raise ExceptionToThrow(e)
        

        或者最后一行应该是raise ExceptionToThrow(str(e))。这取决于您的异常是如何定义的。示例:

        try:
            raise TypeError('foo')
        except TypeError, t:
            raise ValueError(t)
        

        这引发了ValueError('foo')

        希望对你有帮助:)

        【讨论】:

        • 不带str()的方法最好;见python.org/dev/peps/pep-3134。还有@vlad-ardelean:您可以使用 ExceptionToThrow e.__cause__ 来获取 ErrorToCatch
        • 请注意,这会丢弃有关原始异常发生位置的信息,但这听起来像是 OP 所要求的。
        猜你喜欢
        • 2010-12-25
        • 2019-11-30
        • 2011-01-22
        • 1970-01-01
        • 1970-01-01
        • 2012-01-13
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        相关资源
        最近更新 更多