2013-05-25 7 views
11

मैं एक प्रोग्राम है जो एक coroutine मुख्य 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

मुझे बिल्कुल समझ में नहीं आता है, लेकिन @gen.coroutine बदलकर @gen.engine अपवाद को ठीक से बुलबुला करने की अनुमति देता है। यह अभी भी असीमित रूप से काम करता है।

+0

अपवादों को संभालने के लिए gen.coroutine "अपवाद" त्रुटियों को पकड़ता है। gen.engine ऐसा मत करो। देखें http://stackoverflow.com/a/23502625/1066801 – M07

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 समारोह वापसी एक tornado.concurrent.Future तो अपवाद नहीं हैं 'नहीं है टी लपेटा

संबंधित मुद्दे

 संबंधित मुद्दे