簡體   English   中英

龍卷風異步回調異常

[英]Tornado asynchronous callback exception

我有一個異步執行的代碼段:

@tornado.web.asynchronous
def execute(self, func, *args):
    def callback(future):
        try:
            to_return = json.dumps(future.result())
            self.write(to_return)
            self.flush()
            self.finish()
        except:
            error = error = self.get_exception()
            self.set_status(500)
            self.finish(json.dumps({"error": error))

    EXECUTOR.submit(
        partial(func, *args)
    ).add_done_callback(
        lambda future: tornado.ioloop.IOLoop.instance().add_callback(
            partial(callback, future)))


def get_exception(self):
    exc_type, exc_obj, tb = sys.exc_info()
    f = tb.tb_frame
    lineno = tb.tb_lineno
    filename = f.f_code.co_filename
    linecache.checkcache(filename)
    line = linecache.getline(filename, lineno, f.f_globals)
    return {'error_msg': 'LINE {} "{}"): {}, {}'.format(filename, lineno, line.strip(), exc_obj, exc_obj)}

這很好用,除非執行被拋出到函數中的某處,否則堆棧跟蹤只會返回到它在回調中被拋出的位置(即執行將來的位置),而不是代碼中實際發生的位置。

是否可以在最初引發異常的實際函數中捕獲異常?

在python 3中,它應該可以正常工作; 在python 2中,雖然我認為您可以為ThreadPoolExecutor編寫一個包裝程序來捕獲更多細節,但您還是不走運。

Python的異常/回溯模型在Python 2和3之間進行了更改:在python 3中,Exception對象攜帶自己的回溯信息,而在python 2中,回溯是一個單獨的對象(通常通過sys.exc_info三元組訪問)。 由於current.futures軟件包是從Python 3反向移植的,因此它僅捕獲異常本身,而不捕獲exc_info三元組,因此丟失了追溯。

Tornado的未來類(tornado.concurrent.Future)具有一些擴展,可以捕獲python 2中的回溯(set_exc_info()方法)。 我認為您可以執行以下操作(未經測試)來替換executor.submit:

def submit_with_traceback(executor, func, *args):
    tornado_future = tornado.concurrent.Future()
    def wrapper():
        try:
            result = func(*args)
        except:
            tornado.future.set_exc_info(sys.exc_info())
        tornado_future.set_result(result)
    # executor.submit() returns a concurrent.futures.Future; ignore it
    executor.submit(wrapper)
    return tornado_future

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM