8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

函数包装时 Python 异常堆栈跟踪不完整

Silas 1月前

6 0

我有两个文件 t.py:import functoolsimport traceback def wrapper(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs)

我有两个文件 t.py

import functools
import traceback


def wrapper(func):
    @functools.wraps(func)
    def wrapped(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            traceback.print_exception(e)

    return wrapped


@wrapper
def problematic_function():
    raise ValueError("Something went wrong")

和t2.py:

from t import problematic_function

problematic_function()

当我从命令行调用时 python t2.py t2.py 包含信息的堆栈跟踪信息 traceback.print_exception(e) 会丢失 t.py 。我得到的是

Traceback (most recent call last):
  File "/home/c/t.py", line 9, in wrapped
    return func(*args, **kwargs)
  File "/home/c/t.py", line 18, in problematic_function
    raise ValueError("Something went wrong")
ValueError: Something went wrong

如果我删除装饰器,我会得到:

Traceback (most recent call last):
  File "/home/c/t2.py", line 3, in <module>
    problematic_function()
  File "/home/cu/t.py", line 17, in problematic_function
    raise ValueError("Something went wrong")
ValueError: Something went wrong

在没有包装器的情况下,如何获取包装函数中的完整堆栈跟踪?谢谢!

帖子版权声明 1、本帖标题:函数包装时 Python 异常堆栈跟踪不完整
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Silas在本站《python》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 您的代码会更改捕获(或未捕获)异常的位置,因此堆栈跟踪也会更改。异常的堆栈跟踪是从引发异常的位置到捕获异常的位置。这有点像 XY 问题。您想要实现什么目的?

  • 执行回到正在运行的框架 之前 抓住堆栈跟踪并将其打印出来 t2.py ,所以程序只是 按照 您要求的方式执行:那些框架不在 堆栈 跟踪中。

    调用堆栈,即进入异常点的帧被分开保存 - 作为对象中的链接链 Frame 。该信息用于在未捕获异常时将其“冒泡”,但只有在达到每个外层时才会将其添加到回溯中。由于您在中捕获了异常 t ,因此这就是您所拥有的。

    您必须“手动”检查框架以获取任何调用者信息 - 您可以将框架作为回溯中的属性获取 - 或者,您可以只检查 sys._getframe() 包装器内部的调用,并通过跟踪 .f_back 属性来跟踪外部框架。

    当然,您想要收集或格式化以便在这些框架上打印的任何信息都由您自己的代码决定。

    def wrapper(func):
        @functools.wraps(func)
        def wrapped(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                # inner trace:
                traceback.print_exception(e)
                # outer trace:
                f = sys._getframe()
                while f:
                     print(f"{f.f_globals.get("__file__", <"unknown">} at line {f.f_lineno}")
                     f = f.f_back
                     # you could use `inspect.getsource` to print lines of code 
              
    
        return wrapped
    
返回
作者最近主题: