2017-07-17 161 views
1

在我的程序中,我正在對某些主機執行一些獲取請求。問題是我無法正確捕捉主機斷開連接時引發的異常。我正在使用龍捲風並且請求是異步的。 考慮下面的代碼:在做龍捲風並行異步請求時捕獲異常

self.http_client = AsyncHTTPClient() 

    try: 
     responses = yield [self.http_client.fetch(theUrl) for theUrl in URLS]            
    except Exception as e: 
     if (e[0] == 111) or (e[0] == 599): 
       #Do something 

當主機斷開,有時我能捕獲異常,但它仍然拋出。我得到例如印刷到我的日誌文件中此錯誤消息:

ERROR:tornado.application:Multiple exceptions in yield list 
Traceback (most recent call last): 
    File "/opt/felix-web-mon/env/lib/python2.7/site-packages/tornado/gen.py", line 828, in callback 
    result_list.append(f.result()) 
    File "/opt/felix-web-mon/env/lib/python2.7/site-packages/tornado/concurrent.py", line 238, in result 
    raise_exc_info(self._exc_info) 
    File "<string>", line 3, in raise_exc_info 
error: [Errno 111] Connection refused 

儘管我在處理我的代碼「111」例外,它仍然被拋出。我懷疑這是由於我使用列表理解(我需要)。 如何在產量表中刪除產品清單中的多個例外''?你可以幫幫我嗎 ?

回答

1

等待多重期貨,通過簡單地產生一個清單,將「拋棄」所有對任何錯誤的迴應。您可以使用:

  • WaiterIterator - 這其中的好處是,你得到結果,當它到達。你並沒有等到所有yield請求完成(特別是最慢的)。
  • 通過raise_error=Falsefetch打壓提高

Exception handling for parallel fetch requests看看,都被描述。

from tornado.gen import coroutine 
from tornado.ioloop import IOLoop 
from tornado.httpclient import AsyncHTTPClient 

@coroutine 
def main(): 
    URLS = [ 
     'http://amazon.com', 
     'https://www.kernel.org/some404', 
     'http://localhost:8787', # connection refused 
     'http://google.com' 
    ] 
    http_client = AsyncHTTPClient() 

    responses = yield [http_client.fetch(theUrl, raise_error=False) for theUrl in URLS] 
    for idx, r in enumerate(responses): 
     print(URLS[idx]) 
     if 200 <= r.code <= 299: 
      print('> ok') 
     elif 300 <= r.code <= 399: 
      print('> ok - redirect') 
     elif 400 <= r.code <= 499: 
      print('> client err: %s' % r.code) 
     elif 500 <= r.code <= 598: 
      print('> server err: %s' % r.code) 
     elif r.code == 599: 
      print('> 599 connection error or timedouted request') 

     # or something like below 
     #try: 
     # res = r.rethorw() 
     #except Exception: 
      # do something 


IOLoop.instance().run_sync(main)