Get Errno from Python Requests ConnectionError?

走远了吗. 提交于 2019-12-03 07:36:32

问题


I'm catching and printing Python Requests ConnectionErrors fine with just this:

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

It prints out messages such as:

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)

and

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)

And many others. What I'm wondering is, what's the best, most Pythonic, way to get that errno that's displaying in the message? I'd like to have a reliable system for catching the issues and offering as helpful and relevant error message to the user as possible. As far as I can tell, ConnectionError is an indirect decedent of BaseException, with no new properties or methods being added beyond what BaseException offers. I'm hesitant to simply use regex because it seems to me I run the risk of assuming all error messages are formatted the same way in all localities.


回答1:


I think you can access it using e.args[0].reason.errno.

This is probably documented somewhere, but usually when I have to track down something like this I just try it at the console and dig around a little bit. (I use IPython so it's easy to do tab-inspection, but let's try it without).

First, let's generate an error using

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

which should give us the error in 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)",),)

Information is usually in 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)",)

Looking inside, we see:

>>> 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 looks encouraging:

>>> 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



回答2:


I had troubles getting the same results with python 3.6 and requests 2.18. I managed to get the errno using the http and socket modules :

import socket, html
try:
    http.client.HTTPConnection('invalid').connect()
except (socket.gaierror, ConnectionError) as e:
    print(e.errno)

Hopefully it helps someonelse.



来源:https://stackoverflow.com/questions/19370436/get-errno-from-python-requests-connectionerror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!