2011-09-25 158 views
4

我想處理的異常出現在AsyncClient.fetch這樣:異常在Python龍捲風處理


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 

我在做什麼錯?

+0

你能夠捕捉到這個例外嗎?看起來像一個異常沒有得到適當提升。 – Glaslos

+0

@格拉斯洛斯,不,我無法抓住它:(。 –

+0

我記得使用龍捲風期間發生的一些異常很難發現,也許看一些正在進行的問題......對不起,我沒有在一段時間內使用了Tornado ... – Glaslos

回答

9

按照Tornado documentation

如果發生錯誤時的獲取,提供給回調類HTTPResponse具有包含請求過程中遇到的異常的非無誤差屬性。 您可以撥打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發送)。這是無害的,但如果真的困擾您,請參閱logging模塊瞭解如何過濾它。

+2

具體來說,'Tornado'記錄日誌到根處理程序,所以你需要把處理程序/過濾器附加到根,如果你想壓制它們。 –

3

我根本不知道龍捲風,但我看了一眼,你根本無法捕捉異常。唯一的例外是在_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, 
          )) 

不知道這是否回答你的問題。

+0

謝謝。我也在研究_Connection和cleaup,但它是龍捲風的內部代碼。至於我應該有一些機制來捕獲自己代碼中的異常。 –

+0

通過查看我認爲沒有修補Tornado的方式是沒有辦法的 –