[英]Python Tornado gen.engine exception handling
我正在使用Tornado 2.4,并且正在尝试集成异步调用。 可以说我需要通过HTTP调用访问远程资源,因此我在tornado.web.RequestHandler
了此功能:
@tornado.web.asynchronous
def get(self, *args):
try:
self.remote_call()
return 'OK'
except Exception, e:
self.handle_exception(e)
@gen.engine
def remote_call(self):
http_client = httpclient.AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, 'http://google.com')
self.process(response)
所以我的问题是,由于remote_call
产生Task
,显然它将退出remote_call
函数并继续get函数。 然后,当我的任务完成时,引擎将处理响应。 但是,如果在self.process(response)
发生错误,则不会被我捕获,因为这部分代码实际上并未在此处调用,但是在我无法控制的引擎内部。
所以我的问题是,我可以对此引擎进行控制吗? 我可以处理错误,可以要求我在功能结束时执行一些特定任务吗?
我可以直接在这样的函数中执行此操作
@tornado.web.asynchronous
def get(self, *args):
self.remote_call()
return 'OK'
@gen.engine
def remote_call(self):
http_client = httpclient.AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, 'http://google.com')
try:
self.process(response)
except:
self.handle_exception(e)
但是我想使处理异常通用,而不是将其复制粘贴到我的每个Handler上。
那我有办法使用龙卷风的引擎吗? 请注意,我正在使用Tornado 2.4,但是如果需要,我可以迁移到3.0。 谢谢
您可以装饰你处理得2.4 get
与呼叫@gen.engine
,包装调用self.remote_call
在gen.Task
,然后yield
从ING:
@tornado.web.asynchronous
@gen.engine
def get(self, *args):
try:
yield gen.Task(self.remote_call)
except Exception, e:
self.handle_exception(e)
self.finish() # Make sure you call this when `get` is asynchronous.
@gen.engine
def remote_call(self):
http_client = httpclient.AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, 'http://google.com')
self.process(response)
这将允许您处理get
的异常,尽管您仍会看到remote_call
中引发异常的回溯。
但是,我强烈建议您升级。 龙卷风现在是4.0版。 在3.0或更高版本中,您可以使用gen.coroutine
代替gen.engine
和web.asynchronous
:
@gen.coroutine
def get(self, *args):
try:
yield self.remote_call()
except Exception, e:
self.handle_exception(e)
self.finish()
@gen.coroutine
def remote_call(self):
http_client = httpclient.AsyncHTTPClient()
response = yield http_client.fetch('http://google.com')
self.process(response)
coroutine
适当地阻止对remote_call
引发的任何异常的追溯,并允许您在get
处理。
好的,谢谢。 但是我必须这样做:
@tornado.web.asynchronous
@gen.engine
def get(self, *args):
try:
yield gen.Task(lambda cb: self.remote_call())
except Exception, e:
self.handle_exception(e)
self.finish() # Make sure you call this when `get` is asynchronous.
@gen.engine
def remote_call(self):
http_client = httpclient.AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, 'http://google.com')
self.process(response)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.