在python 3中,使用较短的回溯重新引发错误

问题描述

我正在尝试创建一个try-except块,该块会重新引发任意异常,但仅将最后一个包括在追溯堆栈中。

类似这样的东西:

import traceback

def my_func(shorten_tracebacks=True):
    try:
        # Do stuff here

    except Exception as e:
        if shorten_tracebacks:
            raise TheSameTypeOfError,e,traceback.print_exc(limit=1)

        else:
            raise(e)

是否有首选的方法

如果很重要,我这样做是为了方便调试在jupyter笔记本电脑中经常使用的某些API-它们往往会生成很长的堆栈跟踪,其中只有最后一块是有用的。这迫使用户滚动很多。如果您不想缩短回溯,可以随时设置shorten_tracebacks=False

解决方法

我的偏好是create a new exception without a context(如果异常具有上下文,python将同时打印该异常和导致该异常的异常,以及导致该异常的异常,依此类推...)>

try:
    ...
except:
    raise Exception("Can't ramistat the foo,is foo installed?") from None

一些最佳做法:

  • 在异常消息中包括相关的调试信息。
  • 使用自定义异常类型,以便调用者可以捕获新异常。
  • 仅捕获您期望的特定错误类型,以使意外错误通过扩展的追溯而消失。

此方法的缺点是,如果异常捕获范围太广,则最终可能会抑制有用的上下文,这对于调试异常非常重要。备用模式可能如下所示:

try:
    ...
except Exception as e:
    if "ramistat not found" in e.message:
        # The ramistat is missing. This is a common kind of error.
        # Create a more helpful and shorter message
        raise Exception("Can't ramistat the foo,is foo installed?") from None
    else:
        # Some other kind of problem
        raise e

从本质上讲,您检查异常,如果异常是您知道如何处理的错误,则将其替换为自定义消息。否则,您将重新引发原始异常,并让用户弄清楚该怎么做。