13

ioloop次のように、メインから定期的に呼び出されるコルーチンを持つプログラムを作成しました。

from tornado import ioloop, web, gen, log
tornado.log.enable_pretty_printing()
import logging; logging.basicConfig()

@gen.coroutine
def callback():
    print 'get ready for an error...'
    raise Exception()
    result = yield gen.Task(my_async_func)

l = ioloop.IOLoop.instance()
cb = ioloop.PeriodicCallback(callback, 1000, io_loop=l)
cb.start
l.start()

私が得る出力は単純です:

$ python2 app.py
get ready for an error...
get ready for an error...
get ready for an error...
get ready for an error...

raise Exception()黙って無視されます。コールバックを変更した場合

def callback():
    print 'get ready for an error...'
    raise Exception()

期待どおりの(そして必要な)完全なスタック トレースを取得します。コルーチンの使用中にそのスタック トレースを取得するにはどうすればよいですか?

4

2 に答える 2

7

@tornado.gen.coroutine関数がオブジェクトを返すtornado.concurrent.Futureようにするため、ラップする必要はありませんが、キーワードtornado.gen.Taskを使用して呼び出すことができます。yield

@tornado.gen.coroutine
def inner():
    logging.info('inner')

@tornado.gen.coroutine
def outer():
    logging.info('outer')
    yield inner()

このように装飾された関数の例外は、このオブジェクトにラップされ、後でそのメソッドtornado.concurrent.Futureを使用して返すことができます。exception()あなたのケースでは、コールバックメソッドを呼び出し、その後、返されたオブジェクトとそれに含まれる例外をtornado.ioloop.PeriodicCallback捨てるだけです。tornado.concurrent.Future例外を検出するには、チェーン呼び出しを使用できます。

@tornado.gen.coroutine
def inner():
    raise Exception()

@tornado.gen.coroutine
def outer():
    try:
        yield inner()   
    except Exception, e:
        logging.exception(e)

しかし、あなたの場合、投げた直後にキャッチする方が実際には簡単です:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import tornado.gen
import tornado.ioloop
import tornado.options
import logging

tornado.options.parse_command_line()

@tornado.gen.coroutine
def callback():
    logging.info('get ready for an error...')
    try:
        raise Exception()   
    except Exception, e:
        logging.exception(e)

main_loop = tornado.ioloop.IOLoop.instance()
scheduler = tornado.ioloop.PeriodicCallback(callback, 1000, io_loop = main_loop)
scheduler.start()
main_loop.start()

@gen.engine関数が a を返さないtornado.concurrent.Futureため、例外はラップされません。

于 2013-05-29T15:13:46.843 に答える
4

正確な理由はわかりませんが、に変更@gen.coroutineすると@gen.engine、例外が適切にバブルアップします。非同期でも動作します。

于 2013-05-25T01:09:35.130 に答える