2017-01-07 7 views
0

Tornadoでは、ExceptionはFuture内にカプセル化され、非同期関数の呼び出し元は例外をアンパックするためにFutureを生成する必要があります。非同期関数の長い呼び出し連鎖がある場合、例外が発生する関数名と行を正しく出力するようにログメッセージを取得するにはどうすればよいですか?例えばコルーチンPython3 + Tornado4.3 +ネイティブロギングモジュールの例外のロギングを修正しました

は、以下のコードで:async_func()で発生した例外がある場合

FORMAT = '%(asctime)s - %(levelname)s - %(filename)s : %(lineno)s'\ 
     ' - %(funcName)20s() - %(message)s\n' 

logging.basicConfig(format=FORMAT) 

... 

@gen.coroutine 
def layer_2(): 
    return(yield async_func()) 

@gen.coroutine 
def layer_1(): 
    return(yield layer_2()) 

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     logging.warning('Error: {}'.format(str(e)) 

、ログメッセージlinenofuncNamemain()のではなく、async_func()のものです。

catchのいずれの解決方法もありますか?yieldと致しますか?ありがとう!

編集1:私の質問に対する答えは、トルネードとは何の関係もないかもしれないことに気付きましたが、私はそれが私の場合であるため、ここに含めるだけです。

答えて

3

私はあなたがPython 3を使っているのを見ています。そして、Python 3では、Futuresの例外は自動的にトレースバックを利用できます。それを印刷するlogging.exceptionに使用します。

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     logging.exception(e) 

loggingで起こっている神秘的なものは何もありません。あなたはトレースバックを自分で印刷することができます:通常の関数呼び出しスタックからのトレースバックに比べ

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     import traceback 
     traceback.print_exc() 

は、このトレースバックはそれにいくつかの余分なものを持っている:gen.Runner.run、トルネードのコルーチン実装の一部への呼び出しを。しかしそれはその目的を果たします:mainがスタックの一番上にあり、async_funcが一番下にあることがわかります。

これはすべての例外にTracebackが付いているためPython 3で動作し、例外処理中にTornadoがコルーチンのトレースバックを例外に正しく付加します。 For some history, see the docs on Future

最後に、gen.coroutineasync defに置き換えると、Python 3.5インタープリタ自体によって実装されたきれいなトレースバックが得られます。

+0

これは非常に便利です!ありがとうございました!私はこれがあなたが私を助けてくれた2番目の質問だと思います! –

関連する問題