
Python异步异常处理的核心在于:异常在 await 表达式处被重新抛出,且传播路径与同步代码逻辑一致,但需注意协程栈与事件循环的交互细节。
await 是异常传播的关键节点
当一个协程中发生异常(如 raise ValueError("oops")),该异常不会立即向上冒泡,而是被封装进返回的 Awaitable 对象(如 Task 或 coroutine)。只有在调用方 await 该对象时,异常才真正抛出到当前协程上下文中。
- 未被
await的协程(比如只调用some_coro()而不加await)相当于“启动但未执行”,异常根本不会触发 - 若用
asyncio.create_task()启动协程,异常会绑定到该 Task;若未显式await task或调用task.exception(),异常会被静默丢弃(Python 3.8+ 默认发出RuntimeWarning) - 在
async with或async for中,退出时若内部协程含未处理异常,也会在对应位置抛出
Task 与 gather 中的异常行为差异
asyncio.create_task() 和 asyncio.gather() 对异常的处理策略不同,直接影响是否中断整个流程:
-
create_task()是“火-and-忘”式调度:异常仅属于该 Task,除非你主动await task或检查task.exception(),否则不会影响其他协程 -
gather(*coros, return_exceptions=False)(默认):任一子协程异常,gather立即取消其余任务,并将首个异常抛出;其余任务的异常被抑制(但可通过return_exceptions=True收集为结果列表中的Exception实例) - 例如:
await asyncio.gather(coro_a(), coro_b()),若coro_a抛ValueError,coro_b可能被取消,且整个表达式抛出ValueError
try/except 在 async 函数中完全有效
异步函数内的 try/except 语句与同步函数行为一致,可捕获 await 表达式抛出的任何异常:
系统简介:冰兔BToo网店系统采用高端技术架构,具备超强负载能力,极速数据处理能力、高效灵活、安全稳定;模板设计制作简单、灵活、多元;系统功能十分全面,商品、会员、订单管理功能异常丰富。秒杀、团购、优惠、现金、卡券、打折等促销模式十分全面;更为人性化的商品订单管理,融合了多种控制和独特地管理机制;两大模块无限级别的会员管理系统结合积分机制、实现有效的推广获得更多的盈利!本次更新说明:1. 增加了新
立即学习“Python免费学习笔记(深入)”;
- 异常被捕获后,协程继续执行后续语句,不会自动中断整个事件循环
- 可在
except块中await其他协程(如记录日志、清理资源),这是同步异常处理做不到的灵活点 - 注意:不能用普通
except捕获未await的协程异常——它压根没发生;也不能跨协程边界直接捕获(比如在父协程 try 里调用子协程却不 await,就捕不到)
取消(Cancellation)引发的 CancelledError 是特殊异常
CancelledError 继承自 BaseException(而非 Exception),因此普通 except Exception: 不会捕获它。这是设计使然,确保协程能响应取消信号:
- 当 Task 被
cancel(),正在await的协程会在下一次事件循环暂停点收到CancelledError - 若想忽略取消(不推荐),需显式
except asyncio.CancelledError:并pass,或使用asyncio.shield()包裹关键操作 - 在
finally或async with __aexit__中可安全执行清理逻辑,因为CancelledError仍会正常传播,保证资源释放
异步异常不是魔法,它遵循明确的传播规则:await 是闸门,Task 是容器,gather 是协调器,而 CancelledError 是系统级信号。理解这些边界,才能写出健壮的异步错误处理逻辑。









