Я обнаружил закрытую проблему в репозитории запросов с прошлого года под названием «Предложение: улучшить повышение статуса, чтобы включить тело ответа, если оно есть», выданное westover , в который он написал:
Требуется более подробная информация об исключении HTTPError. API, с которым я работаю, отправляет обратно 400, но в нем также есть текстовое / json тело. Было бы неплохо, если бы функция lift_for_status () включала текст ответа, если он был.
Он также предоставил небольшую обходную функцию, которая стала основой причины, по которой обсуждение перешло в обсуждение запроса на извлечение :
import requests
from requests.exceptions import HTTPError
def expanded_raise_for_status(res):
"""
Take a "requests" response object and expand the raise_for_status method to return more helpful errors
@param res:
@return: None
"""
try:
res.raise_for_status()
except HTTPError as e:
if res.text:
raise HTTPError('{} Error Message: {}'.format(str(e.message), res.text))
else:
raise e
return
Я принял это в свой существующий класс и, по сути, jwodder также указал, что он расширяет / перехватывает Response.raise_for_status()
метод, который вызывает HTTPError(RequestsException)
класс всякий раз, когда используется raise_for_status()
пользователями, чтобы подать сообщение об ошибке из ответа сервера, как правило, в виде assert response.status_code == 200, raise_for_status()
. Это достигается путем добавления Response.text
(или content
/ json
методов) к сообщению об исключении и возвращает тело ответа вместо текущего кода возврата <self.status_code, self.reason, self.url>
, который переводится в 400 Bad Requests <url>
.
def raise_for_status(self):
"""Raises stored :class:`HTTPError`, if one occurred."""
http_error_msg = ''
if isinstance(self.reason, bytes):
# We attempt to decode utf-8 first because some servers
# choose to localize their reason strings. If the string
# isn't utf-8, we fall back to iso-8859-1 for all other
# encodings. (See PR #3538)
try:
reason = self.reason.decode('utf-8')
except UnicodeDecodeError:
reason = self.reason.decode('iso-8859-1')
else:
reason = self.reason
if 400 <= self.status_code < 500:
http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url)
elif 500 <= self.status_code < 600:
http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url)
if http_error_msg:
raise HTTPError(http_error_msg, response=self)
(в этом ответе он далее изложил причину, по которой он считает, что она заслуживает особой возможности, но запрос на получение ответа был отклонен, и я думаю, что сопровождающий также имел хорошие моменты), это может привести к другим исключения или более осложнения, если не использовать вдумчиво / экономно, учитывая популярность модуля и широкие причины его использования.