如何在另一个异常中包装一个异常并在Python中记录对原始异常的追溯?
答案 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