Python 异常层次与异常链
内置异常层次、领域异常设计,以及 raise from / __cause__ 保留失败因果链。
#type / concept
#status / growing
#tech / dev
#resource / python
#tech / lang / python
[!info] 关联笔记
Python 异常层次与异常链
这个概念为什么出现
线上只看到 ValueError: bad 却不知道是 JSON 解析失败还是业务校验失败,排障成本陡增。需要:
- 合理的异常类型层次
raise New from original保留因果
[!abstract] 一句话理解 异常是类层次;捕获应按具体程度排列;
raise ... from ...建立__cause__链,便于日志与except策略。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:支付回调解析失败包装为领域错误
# payment_exc_chain.py
# 业务意图:底层 JSON 错误包装为 PaymentCallbackError,保留 cause。
# 教学点:
# - 自定义异常;
# - raise from;
# - __cause__。
import json
class PaymentCallbackError(Exception):
"""支付回调无法被接受。"""
def parse_callback(raw: str) -> dict:
try:
data = json.loads(raw)
except json.JSONDecodeError as exc:
raise PaymentCallbackError("invalid callback json") from exc
if "payment_id" not in data:
raise PaymentCallbackError("missing payment_id")
return data
def main() -> None:
try:
parse_callback("{")
except PaymentCallbackError as exc:
print("type:", type(exc).__name__)
print("msg:", exc)
print("cause:", type(exc.__cause__).__name__, exc.__cause__)
if __name__ == "__main__":
main()
建议运行:
python payment_exc_chain.py
期望输出:
type: PaymentCallbackError
msg: invalid callback json
cause: JSONDecodeError Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
结合场景再看三个关注点
- 对外类型稳定(PaymentCallbackError),对内仍能见 JSONDecodeError。
- 缺字段可不带 cause,本身就是领域问题。
- 日志应打印链,而不是只
str(exc)。
核心概念与准确模型
层次(节选)
BaseException → Exception → ValueError / TypeError / OSError / RuntimeError …
- 不要捕获
BaseException(会含 KeyboardInterrupt 等) - 库错误优先继承
Exception
链式
| 形式 | 含义 |
|---|---|
raise X from e | 显式 cause |
raise X from None | 抑制上下文 |
| 在 except 中 raise X | 可能带 __context__ |
边界情况与反直觉行为
from None会丢掉调试线索,仅在确认噪声时使用。- 多个 except 顺序:先子类后父类。
- 异常组
ExceptionGroup(3.11+)用于并发多错误。
常见误区
[!warning] 常见误区:所有失败都 ValueError 错误理解:省事。
正确模型:调用方需要分支的失败应可区分类型。
工程实践
- 包内定义
PackageError基类 - 边界翻译异常,核心少捕多抛
- 测试断言类型与 cause
本节总结
层次服务语义,链接服务排障。二者一起才构成可运营错误模型。
自测题
- 为什么不建议
except BaseException? raise X from e的价值?
参考答案
- 会捕获系统退出/中断类异常,干扰正常控制。
- 保留根因,便于日志与上层决策。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Exception hierarchy | 文档 | 内置树 |
| raise | 规范 | from 子句 |