繁体   English   中英

Python Tornado中的异常处理

[英]Exception handling in Python Tornado

我试图以这种方式处理AsyncClient.fetch中发生的异常:


from tornado.httpclient import AsyncHTTPClient
from tornado.httpclient import HTTPRequest
from tornado.stack_context import ExceptionStackContext
from tornado import ioloop

def handle_exc(*args):
    print('Exception occured')
    return True

def handle_request(response):
    print('Handle request')

http_client = AsyncHTTPClient()

with ExceptionStackContext(handle_exc):
    http_client.fetch('http://some123site.com', handle_request)

ioloop.IOLoop.instance().start()

并看到下一个输出:


WARNING:root:uncaught exception
Traceback (most recent call last):
  File "/home/crchemist/python-3.2/lib/python3.2/site-packages/tornado-2.0-py3.2.egg/tornado/simple_httpclient.py", line 259, in cleanup
    yield
  File "/home/crchemist/python-3.2/lib/python3.2/site-packages/tornado-2.0-py3.2.egg/tornado/simple_httpclient.py", line 162, in __init__
    0, 0)
socket.gaierror: [Errno -5] No address associated with hostname
Handle request

我究竟做错了什么?

根据龙卷风文件

如果在获取期间发生错误,则给予回调的HTTPResponse具有非None错误属性,该属性包含请求期间遇到的异常。 您可以调用response.rethrow()来在回调中抛出异常(如果有)。

from tornado.httpclient import AsyncHTTPClient
from tornado.httpclient import HTTPRequest
from tornado.stack_context import ExceptionStackContext
from tornado import ioloop

import traceback

def handle_exc(*args):
    print('Exception occured')
    return True

def handle_request(response):
    if response.error is not None:
        with ExceptionStackContext(handle_exc):
            response.rethrow()
    else:
        print('Handle request')

http_client = AsyncHTTPClient()

http_client.fetch('http://some123site.com', handle_request)
http_client.fetch('http://google.com', handle_request)

ioloop.IOLoop.instance().start()

您在控制台上看到的消息只是一个警告(通过logging.warning发送)。 这是无害的,但如果它真的困扰你,请参阅日志模块以了解如何过滤它。

我根本不知道龙卷风,但是我看了一下,你根本无法捕捉异常。 异常是在_HTTPConnection()的构造函数中生成的,并且该构造函数中的大多数代码已经被不同的堆栈上下文包装:

    with stack_context.StackContext(self.cleanup):
        parsed = urlparse.urlsplit(_unicode(self.request.url))
        [...]

因此,基本上只要在那里生成异常(在您的示例中为gaierror),它就会被捕获并通过self.cleanup处理,然后生成599响应AFAICT:

@contextlib.contextmanager
def cleanup(self):
    try:
        yield
    except Exception, e:
        logging.warning("uncaught exception", exc_info=True)
        self._run_callback(HTTPResponse(self.request, 599, error=e,
                            request_time=time.time() - self.start_time,
                            ))

不确定这是否回答了你的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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