2012-02-13 51 views
6

我已经生成了一个Greenlet并将其链接到可调用对象。一段时间后,Greenlet失败并带有例外。链接的可调用函数被调用。这非常棒!如何捕捉gevent中的回溯

这里的问题:

的异常回溯出现在我的控制台上,如你所期望的。但是我想要在链接可调用中使用这个回溯做些事情。我如何访问链接可调用中的回溯?

(我的第一直觉是使用traceback.extract_stack(),但事实证明,提供链接的可调用本身,而不是对异常的跟踪信息。)

回答

15

当Greenlet死亡时,追踪故意不保存。如果它被保存了,它会保留许多预期将被删除的对象,这对于管理某些资源(打开文件或套接字)时尤其重要。

如果你想保存回溯,你必须自己做。

+1

这是一个权威的答案。谢谢,丹尼斯。 – kkurian 2012-02-14 17:44:48

1

只要确保你抢Greenlet的exception值,并把它的Greenlet之外,例如get返回或者返回的值或提高INTERNA l例外。

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 

应该给你你需要的东西。

+0

我试图链接调用(如,foo = gevent.Greenlet(X)中得到回溯; foo.link_exception(条); foo.start(); ; <现在我们在酒吧()> ) - 在bar()中执行你建议的内容不会产生异常的追踪,因为它是在foo中引发的,它会在异常中产生追踪,因为它是在bar中引发的。 – kkurian 2012-02-13 22:52:45

+0

也许你应该在上面粘贴你的代码,你的问题似乎是一个范围问题,如果我们能看到你是如何设置你的范围,调试会更容易。 – 2012-02-14 00:01:08

0

由于使用Greenlet.link_exception斯蒂芬·迪尔的解决方案的替代品。

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) 
+0

你会产卵,然后链接,而不是创建,链接,并开始?有没有实际的区别? – kkurian 2016-10-11 17:11:19

+0

这是否解决了我对迪尔解决方案提出的意见? – kkurian 2016-10-11 17:14:12

+0

好吧,我想理论上greenlet可能会在链接创建之前崩溃。 – renstrm 2016-10-11 19:59:40