理解和调试 `asyncio.TimeoutError from None` 错误

Posted

技术标签:

【中文标题】理解和调试 `asyncio.TimeoutError from None` 错误【英文标题】:Understanding & debugging `asyncio.TimeoutError from None` error 【发布时间】:2021-08-02 06:48:03 【问题描述】:

我遇到了 aiohttp 的问题,我得到以下错误但不确定修复它的最佳方法:

Traceback (most recent call last):
  File "/app/app/services/file_ingestion_utils.py", line 110, in send_api_request
    async with session.post(url, headers=self.headers, data=payload) as response:
  File "/usr/local/lib/python3.8/site-packages/aiohttp/client.py", line 1117, in __aenter__
    self._resp = await self._coro
  File "/usr/local/lib/python3.8/site-packages/aiohttp/client.py", line 544, in _request
    await resp.start(conn)
  File "/usr/local/lib/python3.8/site-packages/aiohttp/client_reqrep.py", line 905, in start
    self._continue = None
  File "/usr/local/lib/python3.8/site-packages/aiohttp/helpers.py", line 656, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError

我从here 看到,这些错误可能有点模糊,但至少在我的情况下,我至少想了解导致这些错误的原因。我的实现如下所示。

    async def async_request(self, df, entity):

        api_request_records = []
        ...some logic to prepare records...


        @backoff.on_exception(backoff.expo, aiohttp.ClientError, max_tries=2)
        async def send_api_request(payload, session):

            url = <some_url>

            try:
                async with session.post(url, headers=self.headers, data=payload) as response:
                      ...some response handling logic...
                    
            except asyncio.TimeoutError:
                self.logger.exception(f"Asyncio TimeoutError on url and payload payload")

        async with aiohttp.ClientSession() as session:
            await asyncio.gather(
                *[send_api_request(api_request_record, session)) for api_request_record in api_request_records])

Q1:当api_request_records 的长度很小时,该方法可以正常工作,但是当它很大时,我更有可能得到TimeoutError。为什么?

Q2:根据here,这里设置ClientSession(timeout=...) 参数是否是秘密,这可能会有所帮助吗?但是,我觉得这个响应可能有点过时,因为它指出现在使用 ClientTimeout 对象而不是 int。相关地,根据官方文档here,默认的 ClientTimeout 似乎已经通过total=None 获得了无限时间,那么这也适用于 ClientSession 吗?

总的来说,希望得到一些帮助和推荐的方法。谢谢!

【问题讨论】:

【参考方案1】:

来自https://docs.aiohttp.org/en/stable/client_quickstart.html#timeouts

默认情况下,aiohttp 总共使用 300 秒(5 分钟)超时,这意味着 整个操作应该在 5 分钟内完成。

因此,

session_timeout = aiohttp.ClientTimeout(total=None)
session = aiohttp.ClientSession(total=session_timeout)

【讨论】:

以上是关于理解和调试 `asyncio.TimeoutError from None` 错误的主要内容,如果未能解决你的问题,请参考以下文章

理解First Chance和Second Chance避免单步调试

debug 调试原理理解

通过调试理解HttpServletResponse中的setHeader()和addHeader()的区别

单步调试理解webpack里通过require加载nodejs原生模块实现原理

实验2 汇编源程序编写与汇编调试

《Windows核心编程》第3章——深入理解handle