Requests: Плохая обработка ошибок в запросах в Python 3 [Во время обработки вышеуказанного исключения произошло другое исключение]

Созданный на 16 дек. 2019  ·  3Комментарии  ·  Источник: psf/requests

Библиотека запросов с Python3 довольно плохо обрабатывает исключения. В python2 это отлично работает. Я попытался запросить GitHub, используя requests.get('https://api.github.com') используя как установленную библиотеку запросов python2, так и библиотеку установленных запросов python3. Они работают по-разному, когда запросы делаются во время отключения сети. (любое исключение обрабатывается по-разному). Попробуйте установить запросы как в python2, так и в python3, и вы можете воссоздать проблему, удалив подключение к Интернету при выполнении запросов. Код, который я использовал
import requests
requests.get('https://api.github.com')

Я установил requests==2.5.3 в свою систему и попытался обновить версию до requests==2.22.0 но проблема все еще сохраняется.

ожидаемый результат

В python2 он дает более чистое исключение, подобное следующему
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 65, in get return request('get', url, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 49, in request response = session.request(method=method, url=url, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 461, in request resp = self.send(prep, **send_kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 573, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 415, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', gaierror(-2, 'Name or service not known'))

Фактический результат

`
Отслеживание (последний вызов последний):
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", строка 157, в _new_conn
(self._dns_host, self.port), self.timeout, ** extra_kw
Файл "/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py", строка 61, в create_connection
для res в socket.getaddrinfo (хост, порт, семейство, socket.SOCK_STREAM):
Файл "/usr/lib/python3.6/socket.py", строка 745, в getaddrinfo
для res в _socket.getaddrinfo (хост, порт, семейство, тип, прото, флаги):
socket.gaierror: [Errno -2] Имя или служба неизвестны

Во время обработки вышеуказанного исключения произошло другое исключение:

Отслеживание (последний вызов последний):
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", строка 672, в urlopen.
chunked = фрагментированный,
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", строка 376, в _make_request
self._validate_conn (соединение)
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", строка 994, в _validate_conn
conn.connect ()
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", строка 334, в соединении
conn = self._new_conn ()
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connection.py", строка 169, в _new_conn
self, "Не удалось установить новое соединение:% s"% e
urllib3.exceptions.NewConnectionError:: Не удалось установить новое соединение: [Errno -2] Имя или служба неизвестны

Во время обработки вышеуказанного исключения произошло другое исключение:

Отслеживание (последний вызов последний):
Файл "/usr/local/lib/python3.6/site-packages/requests/adapters.py", строка 449, в отправке
тайм-аут = тайм-аут
Файл "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", строка 720, в urlopen.
метод, URL, ошибка = e, _pool = self, _stacktrace = sys.exc_info () [2]
Файл "/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py", строка 436, с приращением
поднять MaxRetryError (_pool, url, error или ResponseError (причина))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool (host = 'api.github.com', port = 443): превышено максимальное количество попыток с url: / (вызвано NewConnectionError (': Не удалось установить новое соединение: [Errno -2] Имя или служба неизвестны ',))

Во время обработки вышеуказанного исключения произошло другое исключение:

Отслеживание (последний вызов последний):
Файл "", строка 1, в
Файл "/usr/local/lib/python3.6/site-packages/requests/api.py", строка 75, в get
запрос на возврат ('get', url, params = params, * kwargs)Файл "/usr/local/lib/python3.6/site-packages/requests/api.py", строка 60, в запросевернуть session.request (метод = метод, url = url, * kwargs)
Файл "/usr/local/lib/python3.6/site-packages/requests/sessions.py", строка 533, в запросе
resp = self.send (подготовка, * send_kwargs)Файл "/usr/local/lib/python3.6/site-packages/requests/sessions.py", строка 646, в отправкеr = adapter.send (запрос, * kwargs)
Файл "/usr/local/lib/python3.6/site-packages/requests/adapters.py", строка 516, в отправке
поднять ConnectionError (e, request = request)
request.exceptions.ConnectionError: HTTPSConnectionPool (host = 'api.github.com', port = 443): Превышено максимальное количество повторных попыток с url: / (вызвано NewConnectionError (': Не удалось установить новое соединение: [Errno -2] Имя или служба неизвестны ',))

`

Шаги размножения

import requests

Системная информация

$ python -m requests.help
Python 2.7.15+ (Python2 version)
requests==2.5.3 (Requests version in python2)
=============================
Python 3.6.9 (Python3 version)
requests==2.5.3(Requests version in python3)
=============================
OS: Ubuntu 18.04.3 LTS

Эта команда доступна только для запросов версии 2.16.4 и выше. В противном случае,
предоставьте основную информацию о вашей системе (версия Python,
операционная система и c).

Самый полезный комментарий

Я только что наткнулся на ту же проблему, есть ли способ продолжить это обходное решение после ошибки?
Моя программа не должна завершаться после возникшего исключения, но я не нашел способа сделать это.

Все 3 Комментарий

Я тоже столкнулся с этой проблемой, но нашел способ сделать результат красивее. Обратите внимание на "от None" в сценарии здесь:

import requests
url = 'http://10.0.0.12/example/'
try:
    requests.get(url, timeout=2)
except requests.exceptions.RequestException:
    raise Exception('Failed to connect to %s' % url) from None

Если вы запустите приведенный выше сценарий, результат будет намного чище:

$ python example.py
Traceback (most recent call last):
  File "example.py", line 6, in <module>
    raise Exception('Failed to connect to %s' % url) from None
Exception: Failed to connect to http://10.0.0.12/example/

Вы можете делать только from None в Python3, и я думаю, что это происходит из этого PEP: https://www.python.org/dev/peps/pep-0409/

Я тоже столкнулся с этой проблемой, но нашел способ сделать результат красивее. Обратите внимание на "от None" в сценарии здесь:

import requests
url = 'http://10.0.0.12/example/'
try:
    requests.get(url, timeout=2)
except requests.exceptions.RequestException:
    raise Exception('Failed to connect to %s' % url) from None

Если вы запустите приведенный выше сценарий, результат будет намного чище:

$ python example.py
Traceback (most recent call last):
  File "example.py", line 6, in <module>
    raise Exception('Failed to connect to %s' % url) from None
Exception: Failed to connect to http://10.0.0.12/example/

Вы можете делать только from None в Python3, и я думаю, что это происходит из этого PEP: https://www.python.org/dev/peps/pep-0409/

Я только что наткнулся на ту же проблему, есть ли способ продолжить это обходное решение после ошибки?
Моя программа не должна завершаться после возникшего исключения, но я не нашел способа сделать это.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги