将异常包装在另一个中并记录原始异常

时间:2019-01-20 18:41:51

标签: python exception logging wrapper

如何在另一个异常中包装一个异常并在Python中记录对原始异常的追溯?

1 个答案:

答案 0 :(得分:1)

from语句的raise子句正是这样做的。它将原始异常包装在包装异常的__cause__属性中。这称为exception chaining,是decorator design pattern的应用。然后,日志记录功能的exc_info参数允许记录原始异常:

import logging

try:
    try:
        raise IndexError("foo")
    except IndexError as e:
        raise KeyError from e
except KeyError as e:
    logging.error("An exception occurred:", exc_info=e.__cause__)

用例

此异常链接机制在某些情况下会派上用场。例如,当用户应该使用具有默认实现的其他接口方法来实现接口的抽象方法时。如果这些辅助方法可以引发异常,则其中某些异常可能重叠(属于同一类型)。因此,实现的抽象方法的调用者将无法区分哪个助手方法引发了异常。在不同的异常类的实例中包装原始异常可以解决此问题。

在此示例代码中,我们有一个用于处理请求的BaseServer接口和一个用户的Server类,该类通过_handle,{{1} }和_parse辅助方法。我们根据_format方法实现中的失败点,使用异常链接机制在_send方法(委托给_callback方法)中记录不同的消息:请求解析,请求处理,响应格式或响应发送。

开发人员代码:

_handle

用户代码:

_handle