【问题标题】:AIOHTTP RetryClient on JSON Decode ErrorsJSON 解码错误的 AIOHTTP RetryClient
【发布时间】:2022-12-30 02:37:03
【问题描述】:

我正在尝试使用 aiohttp_retry 的 RetryClient 来解决随机 JSON 解码错误,但重试似乎不起作用。 JSON 解码错误可以重试吗?

错误 - 消息='尝试使用意外的 mimetype 解码 JSON:text/html;字符集=utf-8'

当我尝试使用调试(最新社区 Pycharm)时,我的应用程序似乎变得混乱并出现错误,但直接运行仍然有效,尽管仍然存在解码错误/异常。错误率是 20 分钟内 3950 个 URI 中的 20 个,但我想在之后手动修复它们。

aiohttp 3.8.3 aiohttp_retry 2.8.3 Pythton 3.10

from aiohttp import TCPConnector

from aiohttp_retry import RetryClient, ExponentialRetry

async def get_parcel_details(client, sem, url):
    async with sem, client.get(url) as resp:
        if resp.status == 200:
            try:
                parcel_details = await resp.json(encoding='UTF-8', content_type='application/json')
                return parcel_details

            except Exception as e:
                logger.error(str(e))
                await asyncio.sleep(2)
                logger.warning(f"sleeping on {url} for 2 seconds, retrying?")
                parcel_details = {'Owner': 'ERROR', 'Rental': False}

                return parcel_details
        else:
            logger.error(resp.status)
async def async_main(APNs: list):
    connector = TCPConnector(ssl=False, limit=15, limit_per_host=10, enable_cleanup_closed=True)
    async with RetryClient(headers=API_HEADER, connector=connector, raise_for_status=True,
                           retry_options=ExponentialRetry(attempts=3)) as retry_client:
        sem = asyncio.Semaphore(20)
        tasks = []
        for apn in APNs:
            parcel_url = f'https://api_endpoint/parcel/{apn}'
            tasks.append(asyncio.create_task(get_parcel_details(retry_client, sem, parcel_url)))

        parcels = await asyncio.gather(*tasks, return_exceptions=True)

        return parcels

我尝试将另一个 get 放入异常中,但让事情变得更糟。

【问题讨论】:

    标签: json python-3.x python-asyncio aiohttp


    【解决方案1】:

    看完帖子:How to retry async requests upon ClientOSError: [Errno 104] Connection reset by peer?

    很明显我正在尝试/排除错误的代码段,我按照他的例子,没有更多的错误!

    async def get_parcel_details(client, sem, url):
    """ Takes in an api client, semaphore, and url to get latest parcel data
        Returns a dictionary
    """
    try:
        async with sem, client.get(url) as resp:
            parcel_details = await resp.json(encoding='UTF-8', content_type='application/json')
            return parcel_details
    
    except (json.JSONDecodeError, aiohttp.client.ClientOSError, aiohttp.client.ContentTypeError,
            aiohttp.ClientResponseError, TypeError) as e:
                await asyncio.sleep(4)
                async with sem, client.get(url) as resp:
                    parcel_details = await resp.json(encoding='UTF-8', content_type='application/json')
    
                return parcel_details
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多