从Python请求ConnectionError获取Errno?

从Python请求ConnectionError获取Errno?,python,python-2.7,exception-handling,python-requests,errno,Python,Python 2.7,Exception Handling,Python Requests,Errno,我正在捕获并打印Python请求ConnectionErrors,仅此即可: 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-472

我正在捕获并打印Python请求ConnectionErrors,仅此即可:

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):url:/api/datastores/06651841-bbdb-472a-bde2-689d8cb8da19超过最大重试次数(由:[Errno 61]连接被拒绝引起)

HTTPSConnectionPool(host='10.100.24.16',port=443):url:/api/datastores/06651841-bbdb-472a-bde2-689d8cb8da19超过了最大重试次数(原因:[Errno 65]没有到主机的路由)

还有很多其他的。我想知道的是,什么是最好的,最具python风格的方式来获取消息中显示的错误?我希望有一个可靠的系统来捕捉问题,并向用户提供尽可能有用和相关的错误消息。据我所知,ConnectionError是BaseException的间接继承人,除了BaseException提供的特性外,没有添加任何新的属性或方法。我不太愿意简单地使用正则表达式,因为在我看来,我有可能假设所有错误消息在所有地方的格式都相同。

我认为您可以使用
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)",),)
往里看,我们看到:

>>> 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']
原因
看起来令人鼓舞:

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

我在使用python 3.6和请求2.18获得相同的结果时遇到了困难。我使用
http
socket
模块成功地获取了错误号:

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

希望这对其他人有所帮助。

+1:干得好!非常感谢你!我已经了解了dir(e)和e.args,但我在那一点上停止了将e.args的元素误认为是字符串,我必须使用regex来提取我想要的信息。使用假URL也很容易产生错误。我一直在使用真正的网址,但我的互联网关闭。。。在产生错误和研究错误之间来回往返是很不方便的。哦,我的上帝-谢谢你-谢谢你-这个错误让我抓狂!在Python 3.8.5中,我在
e.errno
e.args[0]
中得到errno;
e.strerror
e.args[1]
中的原因文本消息。
>>> 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
import socket, html
try:
    http.client.HTTPConnection('invalid').connect()
except (socket.gaierror, ConnectionError) as e:
    print(e.errno)