如何在gevent中捕获 traceback

6 投票
4 回答
3448 浏览
提问于 2025-04-17 12:58

我创建了一个叫做Greenlet的东西,并把它和一个可以调用的函数连接在一起。过了一段时间,这个Greenlet出错了,抛出了一个异常。然后,连接的那个函数被调用了。这一切都很好!

但是,这里有个问题:

异常的追踪信息会在我的控制台上显示出来,这很正常。但是我想在那个连接的函数里处理这个追踪信息。我该怎么在这个函数里获取到追踪信息呢?

(我最开始的想法是用traceback.extract_stack(),但结果发现这个方法提供的是连接的函数自己的追踪信息,而不是异常的追踪信息。)

4 个回答

1

只要确保你获取到Greenlet的exception值,并把它抛到Greenlet外面就行了。比如说,get这个方法要么返回你想要的值,要么抛出内部的异常。

import traceback
import gevent

def fail():
    return 0/0

gl = gevent.spawn(fail)

try:
    gl.get()
except Exception as e:
    stack_trace = traceback.format_exc() # here's your stacktrace

这样应该能满足你的需求。

2

这是一个关于使用 Greenlet.link_exception 的替代方案,灵感来自 Stephen Diehl 的解决办法。

import traceback

import gevent

def job():
    raise Exception('ooops')

def on_exception(greenlet):
    try:
        greenlet.get()
    except Exception:
        err = traceback.format_exc()
        # Do something with `err`

g = gevent.spawn(job)
g.link_exception(on_exception)
17

当Greenlet(一个轻量级的线程)结束时,错误追踪信息是故意不保存的。如果保存了这些信息,会导致很多本来应该被删除的对象继续存在,这在某些情况下是很重要的,特别是当这些对象管理一些资源(比如打开的文件或网络连接)时。

如果你想保存这个错误追踪信息,就得自己去做。

撰写回答