2012-02-13 10 views
6

私はGreenletを生成し、呼び出し可能にリンクしました。しばらくして、グリーンレットは例外で失敗します。リンクされた呼び出し可能関数が呼び出されます。それはすべて素晴らしいです!ここでgeventでトレースバックをキャプチャする方法

は問題だ:

あなたが期待通りの例外のためのトレースバックは、私のコンソール上に表示されます。しかし、私は、リンクされた呼び出し可能なコールバック内のそのトレースバックで物事をしたい。リンクされた呼び出し可能コード内でそのトレースバックにアクセスするにはどうすればよいですか?

(私の最初の本能はtraceback.extract_stack()を使用していたが、それはそれはリンク呼び出し可能自身のためではなく、例外のためのトレースバックを提供判明。)

答えて

15

グリーンレットが死んだとき、トレースバックは意図的に保存されません。保存されていれば、削除されることが予想される多くのオブジェクトが生き続けるでしょう。特に、オブジェクトがリソース(オープンファイルまたはソケット)を管理している場合に重要です。

トレースバックを保存する場合は、自分で行う必要があります。

+1

それは正式な答えです。ありがとう、デニス。 – kkurian

1

ちょうどあなたがGreenletのexception値を取得し、Greenlet外に投げることを確認し、例えばget戻り値が返されたかINTERNAを上げるのいずれか例外です

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(bar); foo.start(); ; ) - bar()内で示唆したことは、fooで発生したExceptionのトレースバックを生成しないので、Exceptionのトレースバックをbarで生成します。 – kkurian

+0

上記のコードを上に貼り付ける必要があります。問題がスコープの問題のように見え、スコープを設定する方法がわかったらデバッグが簡単になります。 –

0

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

作成、リンク、開始するのではなく、リンクを作成してリンクしますか?実際的な違いはありますか? – kkurian

+0

これは私がDiehlの解説にコメントした懸念に対応していますか? – kkurian

+0

まあ、私は理論的には、この方法でリンクが作成される前にグリーンレットがクラッシュする可能性があると思います。 – renstrm

関連する問題