如何在引发异常时修改Python追踪对象?
我正在开发一个Python库,供第三方开发者用来为我们的核心应用写扩展。
我想知道,是否可以在抛出异常时修改错误追踪信息,这样最后的调用栈帧就显示开发者代码中调用库函数的地方,而不是库中抛出异常的那一行。此外,调用栈底部还有一些帧是关于加载代码时使用的函数的引用,我也希望能把这些去掉。
提前感谢任何建议!
7 个回答
15
看看jinja2在这里做了什么:
https://github.com/mitsuhiko/jinja2/blob/5b498453b5898257b2287f14ef6c363799f1405a/jinja2/debug.py
虽然看起来不太好,但它似乎能完成你需要的功能。我就不把例子复制过来了,因为内容比较长。
17
你可以通过使用 traceback 的 tb_next 元素,轻松地去掉错误追踪信息的顶部部分:
except:
ei = sys.exc_info()
raise ei[0], ei[1], ei[2].tb_next
tb_next 是一个只读属性,所以我不知道有什么方法可以从底部删除内容。你可能可以尝试修改属性机制来访问这个属性,但我不知道具体怎么做。
1
关于不改变错误追踪信息的事情,你提到的两个要求其实可以用更简单的方法来实现。
- 如果开发者的代码捕获了库里的异常,然后又抛出了一个新的异常,那么原来的错误追踪信息就会被丢掉。这是处理异常的常见方式……如果你只是让原来的异常继续抛出,但又把上面的部分去掉,那么最后的错误追踪信息就没什么意义了,因为追踪信息的最后一行本身并不能引发这个异常。
- 如果你想去掉最后几行追踪信息,可以请求缩短你的错误追踪信息……像 traceback.print_exception() 这样的函数有一个“限制”参数,你可以用它来跳过最后几条记录。
不过,如果你真的需要修改错误追踪信息,实际上是可以做到的……但你会在哪里做呢?如果是在最上层的包装代码里,你可以直接获取错误追踪信息,切掉你不想要的部分,然后用“traceback”模块里的函数来格式化或打印你想要的样子。