You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何触发asyncio.exceptions.CancelledError?程序终止异常求助

程序终止时触发CancelledError与KeyboardInterrupt问题

前天之前程序可正常运行,如今每次点击IDE停止按钮(未使用Ctrl+C)终止程序都会触发报错,报错信息如下:

Traceback (most recent call last):
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\BOT\MAIN.py", line 437, in main
    await dp.start_polling(bot)
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\venv\Lib\site-packages\aiogram\dispatcher\dispatcher.py", line 543, in start_polling
    done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 418, in wait
    return await _wait(fs, timeout, return_when, loop)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 525, in _wait
    await waiter
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\ALEXE\PycharmProjects\MY-TELEGRAM-BOT\BOT\MAIN.py", line 442, in <module>
    asyncio.run(main())
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\ALEXE\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 123, in run
    raise KeyboardInterrupt()
KeyboardInterrupt

Process finished with exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)

核心代码如下:

async def main():
    try:
        await client.start()
        await client.connect()
        await dp.start_polling(bot)
    finally:
        await client.disconnect()

if __name__ == "__main__":
    asyncio.run(main())

问题分析

  1. IDE停止按钮本质是向进程发送中断信号,和Ctrl+C触发的信号类型一致,Python asyncio会将其转化为KeyboardInterrupt;异步任务被强制中断时,会先抛出CancelledError,这属于异步任务终止的正常逻辑,之前未出现可能是IDE更新、依赖包升级或asyncio内部行为调整导致的表现差异。
  2. 当前代码未捕获中断类异常,导致异常栈被完整输出,看起来像是错误,但实际是中断触发的正常流程。

解决方案

修改代码,显式捕获中断类异常,同时保证资源正常释放:

import asyncio

async def main():
    try:
        await client.start()
        await client.connect()
        await dp.start_polling(bot)
    except (asyncio.CancelledError, KeyboardInterrupt):
        # 捕获中断异常,避免不必要的报错栈输出
        pass
    finally:
        await client.disconnect()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

额外建议

  • 若使用aiogram 2.x版本,可给dp.start_polling()添加skip_updates=True参数,减少终止时的残留任务
  • 在finally块中添加日志记录,确认client.disconnect()是否正常执行,方便后续排查资源释放问题

内容的提问来源于stack exchange,提问作者XTLSREALITY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:07:48