You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python包内异常如何组织?服务与HTTP模块异常处理方案抉择

异常组织方案分析与选择

核心需求回顾

你的service包对外需暴露统一的ServiceError异常,该异常要支持as_json()序列化,外部调用方仅需处理这一种异常类型即可。

两种方案的优劣对比

方案1:http.py定义专属异常,service.py捕获后转抛ServiceError

  • 优势:
    • 模块解耦:http.py无需依赖包内的ServiceError,可独立复用(比如其他项目能直接引入这个http模块,不用连带引入service的异常定义)
    • 对外接口纯净:service层统一收口所有底层异常,外部调用方不用关心http模块的内部异常细节,只需处理ServiceError
  • 劣势:
    • 需额外编写异常转换代码:service.py要捕获http模块的所有可能异常,再包装成ServiceError,增加了少量冗余逻辑
    • 易丢失底层细节:需要手动将http异常的错误码、消息等信息传递到ServiceError中,若处理不当会遗漏调试关键信息

方案2:http.py直接抛出共享的ServiceError

  • 优势:
    • 代码简洁:无需额外的异常转换逻辑,http模块直接抛出符合对外要求的异常
    • 异常信息传递直接:底层错误细节可直接封装到ServiceError中,无需二次处理
  • 劣势:
    • 模块耦合:http.py依赖包内的ServiceError,无法脱离service包单独使用
    • 异常边界模糊:http模块的内部异常直接暴露为上层业务异常,不符合“底层模块抛出自身专属异常,上层模块负责转换适配”的分层设计原则

关于errors.py的“代码异味”问题

单独的errors.py本身并非必然是代码异味,关键看设计方式:

  • 如果只是把所有异常无规则地堆砌进去,确实会变成类似utils.py的“垃圾桶”模块
  • 但如果按职责划分(比如拆分基础异常、业务异常、HTTP相关异常等),或者仅存放包对外暴露的公共异常,那就是合理的结构。比如可以在errors.py中定义对外的ServiceError,而http模块定义自己的内部异常(如HTTPRequestError),再由service层负责转换为ServiceError

最终建议

优先选择方案1,理由如下:

  1. 职责清晰:http模块专注于HTTP请求逻辑,抛出自身专属异常;service模块作为对外入口,负责将底层异常转换为统一的ServiceError,符合单一职责原则
  2. 复用性强:http模块不依赖service包的异常定义,后续可轻松在其他项目中复用
  3. 接口稳定:即使底层http模块的异常类型发生变化,只要service层的转换逻辑适配调整,对外的ServiceError接口可以保持不变,不会影响调用方

若担心异常转换的冗余代码,可以在service层封装一个统一的异常转换工具函数,示例如下:

# service.py
from .http import HTTPTimeoutError, HTTPError
from .errors import ServiceError

def _convert_http_error(exc):
    error_code_map = {
        HTTPTimeoutError: "HTTP_REQUEST_TIMEOUT",
        # 可扩展其他HTTP异常与错误码的映射
    }
    error_code = error_code_map.get(type(exc), "UNKNOWN_ERROR")
    return ServiceError(message=str(exc), code=error_code)

def do(...):
    try:
        # 调用http模块的请求逻辑
        return http.send_request(...)
    except HTTPError as exc:
        # 保留异常链,方便调试
        raise _convert_http_error(exc) from exc

内容的提问来源于stack exchange,提问作者ReturnedVoid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:12:47