2013-10-14 79 views
9

我趕上印刷Python的請求ConnectionErrors罰款只是這樣的:從Python獲取Errno請求ConnectionError?

except requests.exceptions.ConnectionError as e: 
    logger.warning(str(e.message)) 

它打印出的信息,如:

HTTPSConnectionPool(host='10.100.24.16', port=443): Max retries exceeded with url: /api/datastores/06651841-bbdb-472a-bde2-689d8cb8da19 (Caused by <class 'socket.error'>: [Errno 61] Connection refused) 

HTTPSConnectionPool(host='10.100.24.16', port=443): Max retries exceeded with url: /api/datastores/06651841-bbdb-472a-bde2-689d8cb8da19 (Caused by <class 'socket.error'>: [Errno 65] No route to host) 

等等。我想知道的是,什麼是最好的,最Pythonic的方式來獲取該消息中顯示的errno?我希望有一個可靠的系統來捕捉問題並儘可能向用戶提供有用的相關錯誤消息。據我所知,ConnectionError是BaseException的一個間接繼承者,沒有新的屬性或方法被添加超出了BaseException提供的。我對使用正則表達式猶豫不決,因爲在我看來,我冒着假設所有錯誤信息在所有地方以相同方式格式化的風險。

回答

23

我認爲你可以使用e.args[0].reason.errno來訪問它。

這可能記錄在某個地方,但通常當我必須追蹤這樣的事情時,我只是在控制檯上嘗試一下,然後挖一點點。 (我使用IPython,因此很容易做標籤檢查,但是我們不用試試)。

首先,讓我們產生使用

import requests 
try: 
    requests.get("http://not.a.real.url/really_not") 
except requests.exceptions.ConnectionError as e: 
    pass 

一個錯誤,應該給我們e錯誤:

>>> e 
ConnectionError(MaxRetryError("HTTPConnectionPool(host='not.a.real.url', port=80): Max retries exceeded with url: /really_not (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)",),) 

信息通常是args

>>> e.args 
(MaxRetryError("HTTPConnectionPool(host='not.a.real.url', port=80): Max retries exceeded with url: /really_not (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)",),) 
>>> e.args[0] 
MaxRetryError("HTTPConnectionPool(host='not.a.real.url', port=80): Max retries exceeded with url: /really_not (Caused by <class 'socket.gaierror'>: [Errno -2] Name or service not known)",) 

看裏面,我們看到:

>>> dir(e.args[0]) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', 
'__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', 
'__str__', '__subclasshook__', '__unicode__', '__weakref__', 'args', 'message', 'pool', 
'reason', 'url'] 

reason看起來令人鼓舞:

>>> e.args[0].reason 
gaierror(-2, 'Name or service not known') 
>>> dir(e.args[0].reason) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', 
'__getitem__', '__getslice__', '__hash__', '__init__', '__module__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', 
'__str__', '__subclasshook__', '__unicode__', '__weakref__', 'args', 'errno', 'filename', 
'message', 'strerror'] 
>>> e.args[0].reason.errno 
-2 
+0

+1:做得非常好!非常感謝你!我已經得到了dir(e)和e.args,但是當時我停止了將e.args的元素誤認爲字符串,我不得不使用正則表達式來提取我想要的信息。 – ArtOfWarfare

+0

使用假的URL也是生成錯誤的好方法。我一直在使用真實的網址,但是我的互聯網被關閉了......不方便在產生錯誤和研究它們之間來回切換。 – ArtOfWarfare

+0

哦,我的領主 - 謝謝你謝謝 - 這個錯誤一直在推動着我! –