asyncio.wait 即使在 `try ... except` 中也返回异常

asyncio.wait returning exception even when in `try ... except`

我的 discord 机器人中有一个 asyncio.wait 语句,因此我可以同时等待多个事件。为了使机器人不会随着时间的推移而陷入困境,我为两个等待语句设置了超时。即使代码在 try ... except 语句中,它仍然会引发错误。 这是导致错误的代码部分:

                try:

                    def check(reaction: discord.Reaction, user):
                        if user != bot.user and message.id == reaction.message.id:
                            return True

                    pending_tasks = [bot.wait_for('reaction_add', timeout=30, check=check),
                                     bot.wait_for('reaction_remove', timeout=30, check=check)]
                    done_tasks, pending_tasks = await asyncio.wait(pending_tasks, return_when=asyncio.FIRST_COMPLETED)

                    reaction, user = await list(done_tasks)[0]

                    #reaction, user = await bot.wait_for(
                    #    "reaction_add", timeout=30, check=check
                    #)

                    user_check = user == ctx.author
                    emoji_check = any(
                        emoji == reaction.emoji for emoji in registered_emojis.keys()
                    )
                    if emoji_check and user_check:
                        next_page = self.paginator.get_page_reaction(reaction.emoji)
                        await message.edit(embed=self.paginator._pages[next_page])

                    #await message.remove_reaction(reaction.emoji, user)

                except asyncio.TimeoutError:
                    bot_help = False
                    for emoji in registered_emojis.keys():
                        await message.remove_reaction(emoji, bot.user)

这是回溯:

Task exception was never retrieved
future: <Task finished name='Task-29' coro=<wait_for() done, defined at /Users/lucas/opt/anaconda3/envs/discord/lib/python3.8/asyncio/tasks.py:434> exception=TimeoutError()>
Traceback (most recent call last):
  File "/Users/lucas/opt/anaconda3/envs/discord/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
    raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError

doc 大约 asyncio.wait:

Note that this function does not raise asyncio.TimeoutError. Futures or Tasks that aren’t done when the timeout occurs are simply returned in the second set.

就个人而言,asyncio.wait 也不会传播来自任务的异常,包括 asyncio.TimeoutError

此外,由于您在至少完成一项任务时使用 return_when=asyncio.FIRST_COMPLETED asyncio.wait returns。其他任务可能仍处于活动状态并引发永远不会检索到的异常。

并且您仅在第一个任务中提取结果:

reaction, user = await list(done_tasks)[0]

但是 done_task 可能包含不止一项已完成的任务,尽管有 FIRST_COMPLETED 标志