requests.exceptions.ConnectionError
inherits from requests.exceptions.RequestException
,
which in turn inherits from IOError
which in turn inherits from EnvironmentError
.
EnvironmentError
is described as containing a 2-tuple value: on element 0,
errno
and on element 1, strerror
(presumably a string description of the
error). For example:
try:
f = open("/foo")
except IOError as e:
print("errno: %s" % e.errno)
print("strerror: %s" % e.strerror)
However, requests
seems to take this concept of the 2-tuple errno/strerror pair
to the extreme. Instead of an integer and string, a ConnectionError
gets as its
pair a requests.package.urllib3.exceptions.ProtocolError
on element 0 and None
on element 1. ProtocolError
similarly violates the errno/strerror tuple promise,
setting a string on element 0 and a socket.gaierror
on element 1. Neither
ConnectionError
nor ProtocolError
set their errno
or strerror
attributes,
so to actually get a string description of a ConnectionError
returned by requests
,
we have to access the args
attribute directly: e.args[0].args[0]
(or more
cryptically: e[0][0]
). Don’t forget to except
the inevitable IndexError
inside your except
block for when indexes change out from under you without
warning.