【发布时间】:2022-11-27 19:45:31
【问题描述】:
感觉我正在慢慢失去理智。我无法捕获 REST-API 请求中的连接错误。我在 stackoverflow 上阅读了至少 20 个类似的问题,尝试了我能想到的所有可能的 except 语句,并尽可能地简化代码以排除某些其他库。
我正在使用 Python 3.7 并请求 2.25.1。这是对我自己的服务器上的 API 的非常基本的调用,有时会失败,但偶尔会失败一次:
try:
response = requests.get(url, headers=api_headers, auth=HTTPBasicAuth(username, password))
except requests.exceptions.ConnectionError:
print("Connection error!")
很抱歉,我无法提供完整的工作示例,因为我没有连接到可公开访问的 API,所以我不得不删除 url、用户名和密码。
即使我尝试捕获连接错误,脚本也会失败并出现以下回溯:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 706, in urlopen
chunked=chunked,
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 382, in _make_request
self._validate_conn(conn)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 1010, in _validate_conn
conn.connect()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 421, in connect
tls_in_tls=tls_in_tls,
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 429, in ssl_wrap_socket
sock, context, tls_in_tls, server_hostname=server_hostname
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 472, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 412, in wrap_socket
session=session
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 850, in _create
self.do_handshake()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 1108, in do_handshake
self._sslobj.do_handshake()
TimeoutError: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 449, in send
timeout=timeout
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 756, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\retry.py", line 532, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
raise value.with_traceback(tb)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 706, in urlopen
chunked=chunked,
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 382, in _make_request
self._validate_conn(conn)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 1010, in _validate_conn
conn.connect()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 421, in connect
tls_in_tls=tls_in_tls,
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 429, in ssl_wrap_socket
sock, context, tls_in_tls, server_hostname=server_hostname
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 472, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 412, in wrap_socket
session=session
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 850, in _create
self.do_handshake()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 1108, in do_handshake
self._sslobj.do_handshake()
urllib3.exceptions.ProtocolError: ('Connection aborted.', TimeoutError(10060, 'Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat', None, 10060, None))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 498, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', TimeoutError(10060, 'Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat', None, 10060, None))
我不明白如果我捕获到那个错误,脚本怎么可能因 requests.exceptions.ConnectionError 而失败?
如果我正确理解回溯,错误不会在我的代码中抛出,因此我无法捕捉到它?我所看到的只是 python 库,如 ssl.py 和 urllib 以及请求,但不是我的代码中的一行。那我怎么抓住它呢?
非常感谢任何帮助!
编辑(因为这在评论中是不可能的)。 @Thomas 发表了一条有用的评论以连接到 httpstat.us:81 进行调试。所以我尝试用 response = requests.get("http://httpstat.us:81") 替换我的 order_response = requests.get() 电话。这是我的代码中的确切块:
try:
order_response = requests.get(order_access_url, headers=api_headers, auth=HTTPBasicAuth(username, password))
if order_response.status_code == 200:
order_content = json.loads(order_response.text)
else:
order_content = ""
except requests.exceptions.ConnectionError:
print("Connection error!")
如果我尝试连接到http://httpstat.us:81,它实际上会捕获错误。如果我故意不抓住它,错误看起来像这样:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 170, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\connection.py", line 96, in create_connection
raise err
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\connection.py", line 86, in create_connection
sock.connect(sa)
TimeoutError: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 706, in urlopen
chunked=chunked,
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 394, in _make_request
conn.request(method, url, **httplib_request_kw)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 234, in request
super(HTTPConnection, self).request(method, url, body=body, headers=headers)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 1229, in request
self._send_request(method, url, body, headers, encode_chunked)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 1275, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 1224, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 1016, in _send_output
self.send(msg)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 956, in send
self.connect()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 200, in connect
conn = self._new_conn()
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 182, in _new_conn
self, "Failed to establish a new connection: %s" % e
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x00000223F9B42860>: Failed to establish a new connection: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 449, in send
timeout=timeout
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 756, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\retry.py", line 574, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='httpstat.us', port=81): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000223F9B42860>: Failed to establish a new connection: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Daten\cloud.bss-archery.com\BSS\_Twain\modules\order_extracts_api.py", line 50, in create_order_analysis
response = requests.get("http://httpstat.us:81")
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "C:\Users\Tilman\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='httpstat.us', port=81): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000223F9B42860>: Failed to establish a new connection: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat'))
所以我仍然很困惑,因为回溯中的最后一个条目实际上是相同的,requests.exceptions.ConnectionError,但它没有被我的真实应用程序捕获。然而,它是由 \lib\site-packages\requests\adapters.py 中的另一行提出的
【问题讨论】:
-
你的脚本叫什么?
-
那重要吗?名称是 order_extracts_api.py
-
我从未见过未显示您的入口点的回溯,这就是我问的原因。我不知道你怎么没有调用堆栈上的东西
-
是的,我也没有。这就是为什么我完全迷路了。我现在使用 Python 已经 5 年了,并且使用 try except 很多,我也阅读了很多回溯,这让我觉得自己完全是个初学者。
-
这将是真的如果您无论如何都可以创建一个最小的可重现示例,那将很有帮助。您可以在接受连接后使用httpstat.us/200?sleep=5000 来提供缓慢的响应,并且(未记录的“功能”)httpstat.us:81 根本不接受连接。
标签: python python-3.x python-requests try-except