自定义异常类必须继承Exception或其子类,推荐分层定义如AuthError、ValidationError;构造函数应支持code、detail等扩展字段;捕获时需用具体类名而非Exception;善用raise...from...保留异常链。

自定义异常类必须继承 Exception 或其子类
Python 中抛出的异常对象必须是 Exception 的实例,否则 raise 会直接报 TypeError: exceptions must derive from BaseException。常见错误是直接继承 object 或写空类,结果运行时报错却找不到原因。
- 正确做法:始终以
class ValidationError(Exception):形式定义 - 业务场景建议分层:如
AuthError(认证)、ValidationError(参数校验)、PaymentError(支付失败),避免全塞进一个BusinessError - 如果需要区分严重等级,可额外继承
RuntimeError或ValueError,但注意语义——比如ValueError适合“输入值非法”,而流程中断应优先用Exception子类
在 __init__ 中预留扩展字段,别只传 message
只接受一个字符串 message 的异常类,在实际调试中很快会捉襟见肘。比如前端需要错误码、后端要记录上下文、日志需结构化字段——这些都得靠构造函数传入。
- 推荐签名:
def __init__(self, message, code=None, detail=None, user_friendly=None): -
code用于映射 HTTP 状态码或内部错误码(如"AUTH_TOKEN_EXPIRED"),避免用数字硬编码 -
detail放技术细节(如{"field": "email", "reason": "invalid_format"}),不暴露给用户 - 初始化时仍调用
super().__init__(message),保证str(exc)可读
捕获时用具体类名,别依赖 except Exception:
全局捕获 Exception 会吞掉你精心设计的异常类型,导致业务逻辑无法分流处理,也掩盖真实问题。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 写法示例:
except ValidationError as e:→ 返回 400;except PaymentError as e:→ 触发退款补偿 - 切忌在中间件或装饰器里无差别
except Exception后又原样raise,这等于没做分类 - 如果必须兜底,至少加日志:
logger.exception("unhandled exception"),而不是静默忽略
配合 raise ... from ... 保留原始异常链
业务异常常由底层异常触发(比如数据库连接失败导致订单创建失败),直接 raise ValidationError(...) 会丢失原始堆栈,排查时只能看到“验证失败”,看不到“其实是 psycopg2.OperationalError”。
- 正确写法:
raise ValidationError("库存校验失败") from original_exc - 这样
traceback.print_exc()会显示两段 traceback,用__cause__关联 - 注意:如果原始异常是系统级致命错误(如
MemoryError),不应用from包装,避免误导——此时该让服务崩,而不是伪装成业务异常
真正难的不是定义几个异常类,而是整个调用链上每层都明确“谁该抛、谁该捕、谁该转译”。漏掉一层,精准报错就断在半路。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










