繁体   English   中英

使用异常链的原因是什么

[英]What is the reason to use exception chaining

最近我在阅读有关异常链接的内容,我不确定何时应该使用这种语法,以及出于什么原因。

我习惯了这样的模式:

try:
    my_function()
exception MyError:
    my_logger.exception("Error occured")
    raise MyProcessError("Process failed")

我注意到,如果我在这里使用异常链接,回溯中的一个文本将被更改,并且 MyProcessError 将具有来自 MyError 的消息的新属性。

try:
    my_function()
exception MyError as err:
    my_logger.exception("Error occured")
    raise MyProcessError("Process failed") from err

跟踪日志中提到的更改是将“在处理上述异常期间,发生另一个异常”替换为“上述异常是以下异常的直接原因”。

那么使用这种语法的原因是什么? 我什么时候应该将它包含到我的代码中? 欢迎提供示例:-)

在异常处理程序中,如果您显式引发异常,您将希望使用from errfrom None (取决于抑制原始回溯是否更有意义)。

如果没有from ,您会收到消息:“在处理上述异常期间,发生了另一个异常”,表明“出了点问题,然后,在尝试从中恢复时,其他事情(可能不相关)出了问题。就是这种情况例如,当您打错字( my_logger.expeption("Error occurred") )或尝试将某些内容保存到无法打开的文件时。

from ,它表明只有一件事情出错了,你没有处理自己,但你有一些对程序员或用户有用的信息。 例如,您可以捕获KeyError并使用消息“试图编辑不存在的小部件”或其他任何内容引发不同的异常。

因此raise SomeException("some description") from err是一种能够解释如果引发err的代码无法做到这一点时出现错误的方法(因为它来自标准库,或者因为它缺乏必要的上下文它被称为),而没有让用户认为两个独立的事情相继出错。

语句raise EXCEPTION from CAUSE等价于:

exc = EXCEPTION
exc.__cause__ = CAUSE
raise exc

此功能有时可用于存储有关异常链的信息,以便在最后一级处理、传输或记录。

例如,在创建自己的库时,我们使用基础 class 创建自己的异常层次结构,并且我们不想从函数中抛出第三个库的异常。 但同时,我们希望将有关原始异常的信息保存为详细信息。


class ThirdPartyLibException(Exception):
    pass


def third_party_lib_foo():
    ...
    raise ThirdPartyLibException('third party exception')

class MyLibException(Exception):
    pass


def my_lib_foo():
    try:
        third_party_lib_foo()
    except ThirdPartyLibException as e:
        raise MyLibException() from e

try:
    my_lib_foo()
except MyLibException as e:
    print('True reason: ', str(e.__cause__))
    # processing

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM