【问题标题】:How to re-raise the same exception without the traceback?如何在没有回溯的情况下重新引发相同的异常?
【发布时间】:2018-05-28 12:23:13
【问题描述】:

except 块中,我想引发相同的异常,但没有堆栈跟踪和没有该异常已被引发为另一个异常的直接原因的信息例外。 (并且无需全局修改sys.tracebacklimit

此外,我有一个非常笨拙的异常类,它解析和修改消息文本,所以我不能只是重现它。

我目前的做法是

try:
    deeply_nested_function_that_raises_exception()
except ClumsyExceptionBaseClass as exc:
    cls, code, msg = exc.__class__, exc.code, exc.msg
raise cls("Error: %d %s" % (code, msg))

我在这里所做的是分解异常信息,重新组装一个带有消息的新异常,该消息将被解析并拆分为错误代码和构造函数中的消息并将其except 块之外引发,以便忘记所有跟踪信息。

有没有更蟒蛇的方式来做到这一点?我想要的只是摆脱嘈杂的(在我的情况下是无用的)追溯,同时保留异常对象中包含的信息..

【问题讨论】:

  • 听起来您想更改异常的表示,而不是更改异常本身。
  • 这里最pythonic的事情就是不理会原来的异常和回溯。就我而言,当有人认为他足够聪明知道原始异常/原始回溯的哪些部分对我有用时,我只是非常讨厌它。碰巧我现在遇到了这个问题生产只是为了获得原始异常和完整的回溯。
  • 我一般不想更改异常表示,但在某些情况下,很明显只需要本地上下文即可找到问题(例如,具有深度嵌套的 get(<name>) 函数查找导致非常明显的KeyError。在具有数千个测试的pytest 场景中,您有时会有数百兆字节的无用堆栈跟踪以及 99% 的重复信息,这使得很难找到 实际问题。

标签: python exception traceback backtrace


【解决方案1】:

在 Python 3 中,您可以使用 with_traceback 删除迄今为止累积的回溯条目:

try: ...
except Exception as e:
  raise e.with_traceback(None)

在 Python 2 中,它只是

try: ...
except Exception as e:
  raise e   # not just "raise"

它当然仍然会显示到 this 行的跟踪,因为它是在异常传播时添加的(再次)。

【讨论】:

    猜你喜欢
    • 2021-12-26
    • 2021-12-27
    • 2016-11-30
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2017-09-03
    • 2022-08-19
    相关资源
    最近更新 更多