asyncio任务异常不会自动传播,需显式await或调用task.exception()捕获;gather默认中断执行,应设return_exceptions=true统一处理;wait返回的任务需手动检查exception;未await的task异常会被静默丢弃。

asyncio.create_task() 里直接 try-except 捕不到异常
asyncio 任务一旦被调度,就脱离了当前协程的执行上下文。你在 create_task() 外面包一层 try-except,根本 catch 不到任务内部抛出的异常——它会被静默吞掉,或只在事件循环关闭时以 Task exception was never retrieved 警告形式出现。
正确做法是让异常“浮上来”:要么 await 任务,要么显式调用 task.exception() 检查。
- 如果任务已结束(
task.done()为真),调用task.exception()会返回异常对象,或返回None(说明正常完成) - 如果任务还在跑,
task.exception()返回None,不能阻塞等待 - 想等结果并捕获异常?直接
await task,这时异常会原样抛出,try-except才有效
asyncio.gather() 的异常默认行为很坑
gather() 默认参数 return_exceptions=False,意味着只要其中一个任务出错,整个 gather() 就立刻中断,抛出第一个异常,其余任务可能还在跑、也可能被取消——你完全不知道其他任务发生了什么。
更糟的是,如果你没加 return_exceptions=True,又没做 cancel 处理,那些“漏网”的任务可能变成孤儿任务,持续占用资源。
- 加
return_exceptions=True后,出错任务会把异常作为普通返回值放进结果列表,类型是Exception实例,不是None - 后续要统一处理:遍历结果,用
isinstance(x, Exception)判断是否失败 - 注意性能:即使某个任务失败,
gather(..., return_exceptions=True)仍会等所有任务结束(除非你手动asyncio.wait(..., return_when=FIRST_EXCEPTION))
asyncio.wait() 中 timeout 和 return_when 影响异常可见性
wait() 本身不抛异常,它只返回已完成/未完成任务集合。异常依然藏在各个 Task 对象里,必须手动检查。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
尤其当设了 timeout 或 return_when=asyncio.FIRST_COMPLETED,很可能你拿到的“已完成”任务里混着异常,而“未完成”任务里也有正在崩溃的——它们还没来得及把异常写进 task.exception()。
- 对
done集合里的每个 task,务必调用task.exception()或task.result()(后者会重新抛异常) - 不要忽略
pending集合:若需清理,应调用task.cancel()并await task确保它真正退出 -
timeout是 wall-clock 时间,不是任务执行时间,网络延迟高时容易误判
使用 asyncio.run() 时顶层异常没被捕获的典型场景
asyncio.run(main()) 会自动创建新事件循环、运行 main 协程、然后关闭循环。但它只捕获 main 协程本身抛出的异常,对里面 spawn 出来的、没被 await 的任务完全不负责。
比如你在 main() 里写了 create_task(crash_soon()) 就返回,那 crash_soon() 的异常永远不会冒到 asyncio.run() 层级。
- 开发阶段可临时加
asyncio.get_event_loop().set_exception_handler(...)捕获未处理异常 - 生产环境更稳妥:用
asyncio.create_task()+asyncio.current_task().add_done_callback(...)给每个任务加兜底处理 - 或者改用
asyncio.run(main(), debug=True),会在控制台打印未检索异常的堆栈(但仅限开发)
异步异常真正的难点不在语法,而在“谁该负责哪一层异常”。任务一旦脱离 await 链,它就自成一个错误边界——没人替你盯着,除非你主动去查 task.exception()。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










