如何为数据库访问层统一声明并引用一组异常集合?
最优异常集合声明方案:自定义异常基类+统一包装机制
核心思路:用自定义基类收拢所有相关异常
比起用元组拼接异常类型,更稳妥的方式是定义一个统一的异常基类,让所有数据库访问相关的异常(自定义、第三方、内置)都关联到这个基类下。这样使用者只需捕获这个基类,就能覆盖所有场景,同时组合其他异常也更直观。
具体实现步骤
- 定义统一基类
class DatabaseAccessError(Exception): """用于捕获所有数据库访问相关异常的基类""" pass
- 自定义异常直接继承基类
class DatabaseDoesNotExistError(DatabaseAccessError): """数据库不存在的自定义异常""" pass
- 第三方/内置异常自动包装
不用在每个操作点手动捕获再抛出,写一个装饰器统一处理:
import functools from requests.exceptions import ConnectionError as RequestsConnError import http.client def wrap_db_exceptions(func): @functools.wraps(func) def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except (RequestsConnError, http.client.IncompleteRead, ConnectionRefusedError) as e: # 保留原异常上下文,方便调试 raise DatabaseAccessError(f"数据库访问失败: {str(e)}") from e return wrapper
给所有数据库操作函数加上这个装饰器:
@wrap_db_exceptions def execute_query(sql): # 数据库操作逻辑 pass
使用者的便捷用法
现在使用者可以轻松捕获所有相关异常,组合其他异常也很清晰:
try: execute_query("SELECT * FROM products") except DatabaseAccessError: # 处理所有数据库访问类异常 handle_db_failure() except (KeyboardInterrupt, ValueError): # 按需组合其他异常类型 handle_other_errors()
可选优化:细化异常分类
如果需要让使用者能精准捕获某类异常,可以在基类下再定义子类:
class DBConnectionError(DatabaseAccessError): """网络连接类异常(连接拒绝、请求失败等)""" pass class DBDataReadError(DatabaseAccessError): """数据读取类异常(比如IncompleteRead)""" pass
然后在装饰器中对应包装成不同子类,使用者可选择捕获基类或具体子类。
关键补充:完善文档说明
一定要在库的文档中明确:
DatabaseAccessError包含哪些子类异常- 哪些第三方/内置异常会被自动包装到这个基类下
可以把这些信息写在DatabaseAccessError的类注释里,或者在函数文档中标注。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

