2012-02-13 34 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