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

Flask待办API异常处理最佳实践咨询

Flask 待办API异常处理最佳实践

核心原则:分层职责边界清晰

Service层专注业务逻辑,不处理HTTP相关内容(状态码、JSON响应);Controller层负责接收请求、调用Service、处理异常并返回标准HTTP响应;DAO层仅做数据库交互,抛出底层异常即可。

具体实现方案

1. 定义业务专属自定义异常

在Service层抛出自定义业务异常,替代返回错误字符串或HTTP相关内容,让Service层职责纯粹,类型提示也更明确。

比如针对非法状态定义异常:

class InvalidStatusError(Exception):
    def __init__(self, invalid_status: str):
        self.invalid_status = invalid_status
        self.valid_options = [status.name for status in ValidStatus]
        super().__init__(f"无效状态:{invalid_status},可选值为:{', '.join(self.valid_options)}")

修改Service层的add_item方法,不再捕获异常,而是将KeyError转换为自定义业务异常抛出:

def add_item(self, name: str, status: str) -> int:
    try:
        valid_status = ValidStatus[status.upper()]
    except KeyError:
        raise InvalidStatusError(status) from None  # 隐藏原始KeyError栈信息,让异常信息更简洁
    inserted_id = self.dao.insert_task(item_name=name, item_status=valid_status)
    return inserted_id

此时Service层返回值始终为int,类型提示干净,完全聚焦业务逻辑。

2. 在Controller层捕获并转换异常

Controller层调用Service方法时,捕获自定义异常及其他可能的异常,统一转换为标准HTTP响应:

from flask import request, jsonify

@app.route('/items', methods=['POST'])
def create_item():
    data = request.get_json()
    try:
        item_id = todo_service.add_item(data['name'], data['status'])
        return jsonify({"new_item_id": item_id}), 201  # 用201表示资源创建成功更符合REST规范
    except InvalidStatusError as e:
        return jsonify({"error": str(e)}), 400
    except KeyError:  # 处理请求参数缺失的情况
        return jsonify({"error": "缺少必填字段:name或status"}), 400
    except Exception:  # 兜底处理未知异常,避免暴露敏感信息
        return jsonify({"error": "服务器内部错误"}), 500

3. 进阶:全局异常处理器减少重复代码

如果多个接口需要处理相同类型的异常,可以用Flask的@app.errorhandler装饰器定义全局异常处理器,避免重复编写捕获逻辑:

@app.errorhandler(InvalidStatusError)
def handle_invalid_status(error):
    return jsonify({"error": str(error)}), 400

@app.errorhandler(500)
def handle_internal_error(error):
    return jsonify({"error": "服务器内部错误"}), 500

此时Controller层可以大幅简化:

@app.route('/items', methods=['POST'])
def create_item():
    data = request.get_json()
    item_id = todo_service.add_item(data['name'], data['status'])
    return jsonify({"new_item_id": item_id}), 201

当Service抛出InvalidStatusError时,全局处理器会自动捕获并返回对应响应。

方案优势

  • 职责分离:各层只做自己擅长的事,符合单一职责原则,代码结构更清晰。
  • 类型安全:Service层返回值类型统一,类型提示准确,避免Union带来的模糊性。
  • 可维护性:异常处理逻辑集中,修改错误响应格式只需调整一处,无需遍历所有Service方法。
  • 扩展性:新增业务场景时,只需定义新的异常类和对应的处理器,无需改动大量现有代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 07:06:32