繁体   English   中英

Python Tornado gen.engine异常处理

[英]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_callgen.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.engineweb.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM