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
标志
我的 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
标志