Как получить тело ответа HTTP 403, используя Python + aiohttp? - PullRequest
1 голос
/ 13 марта 2019

Я использую Python 3.6 и библиотеку aiohttp для отправки запроса API Post на сервер. Если я использую неправильное имя пользователя при выполнении запроса, я получаю ошибку HTTP 403, как и ожидалось. Когда я делаю этот запрос в Почтальоне, тело ответа показывает:

{"error_message": "No entitlements for User123"}

Однако, когда я делаю запрос, используя aiohttp, я нигде не вижу этого тела ответа. Сообщение просто говорит "Запрещено". Как я могу получить сообщение об ошибке выше в моем коде Python?

Edit: вот мой код aiohttp, хотя он довольно прост:

try:
    async with self.client_session.post(url, json=my_data, headers=my_headers) as response:
        return await response.json()
except ClientResponseError as e:
    print(e.message)  # I want to access the response body here
    raise e

Редактировать 2: я нашел обходной путь. Когда я создаю client_session, я устанавливаю значение rise_for_status в False. Затем, когда я получаю ответ от вызова API, я проверяю, имеет ли статус> = 400. Если это так, я сам обрабатываю ошибку, которая включает тело ответа.

Редактировать 3: Вот код моего обходного пути:

self.client_session = ClientSession(loop=asyncio.get_event_loop(), raise_for_status=False)
####################### turn off the default exception handling ---^

try:
    async with self.client_session.post(url, json=my_data, headers=my_headers) as response:
    body = await response.text()

    # handle the error myself so that I have access to the response text
    if response.status >= 400:
        print('Error is %s' % body)
        self.handle_error(response)

1 Ответ

1 голос
/ 04 июня 2019

Да, это действительно может сбить с толку, если вы пришли из пакета requests, у которого есть объекты исключений, имеющие атрибут .request.response (или наоборот).

Вы уже выяснили этоочевидно, но вот правильный ответ:

async with session.post(...) as response:
    try:
        response.raise_for_status()
    except ClientResponseError as err:
        logger.error("Error: %s, Error body: %s", err, (await response.text()))

    return await response.json()
...