![](/img/trans.png)
[英]Tornado IOLoop Exception in callback None in Celery worker
[英]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.