← 返回题目列表

Flask 如何做错误处理?errorhandler 和 abort 有什么区别?

高频 中等 第 8 / 27 题 更新于 2026/07/31
Flaskerrorhandlerabort异常处理

简化版

Flask 可以用 abort() 主动抛出 HTTP 错误,也可以用 @app.errorhandler 注册错误处理器,把异常或状态码转换成统一响应。abort(404) 是触发错误,errorhandler 是定义错误发生后如何返回。

详细版

from flask import abort, jsonify

@app.get("/users/<int:user_id>")
def get_user(user_id):
    user = find_user(user_id)
    if not user:
        abort(404)
    return jsonify(user)

@app.errorhandler(404)
def not_found(e):
    return jsonify(error="not found"), 404

生产 API 通常要统一错误格式、记录 5xx 异常、区分业务错误和系统错误。面试要强调:不要把所有异常都吞成 200,也不要把内部堆栈暴露给用户。

完整版教学

一、为什么需要统一错误处理

接口调用方需要稳定错误格式。一个接口返回 HTML 错误页,一个返回 JSON,一个返回 200 但里面写 error,会让前端和调用方很痛苦。

{"code": "NOT_FOUND", "message": "user not found"}

统一错误处理让错误可读、可监控、可告警。

二、abort 做什么

abort() 用于主动终止请求并抛出 HTTPException。比如资源不存在、无权限、参数不合法。

if not user:
    abort(404, description="user not found")

它不是返回响应,而是抛出异常,由 Flask 错误处理机制接管。

三、errorhandler 做什么

errorhandler 注册某类错误的处理逻辑。可以按状态码,也可以按异常类注册。

@app.errorhandler(ValueError)
def handle_value_error(e):
    return jsonify(error=str(e)), 400
机制作用
abort触发 HTTP 错误
errorhandler生成错误响应
register_error_handler动态注册处理器

四、蓝图错误处理

Blueprint 也可以注册 errorhandler,用于模块级错误处理。但 404 路由未匹配有时还没进入蓝图,可能由 app 级处理器处理。

bp = Blueprint("api", __name__)

@bp.errorhandler(400)
def bad_request(e):
    ...

大型项目通常 app 级统一兜底,蓝图级处理模块特殊错误。

五、5xx 错误如何处理

5xx 表示服务端错误,要记录堆栈和上下文,但响应给用户要克制。生产不能把 traceback 原样返回。

@app.errorhandler(Exception)
def handle_unexpected(e):
    app.logger.exception("unexpected error")
    return jsonify(error="internal server error"), 500

对用户隐藏内部细节,对日志保留足够上下文。

六、业务错误和 HTTP 错误

业务错误可以定义自定义异常,包含 code、message、status_code。错误处理器统一转换成 JSON。

class BusinessError(Exception):
    status_code = 400

这样业务代码可以 raise BusinessError(...),不用每层手写 jsonify。

七、常见误区与追问

  • 误区:所有错误都返回 200。 会破坏 HTTP 语义,监控也难做。
  • 误区:errorhandler 里不需要日志。 5xx 必须记录堆栈和上下文。
  • 误区:abort 和 return 一样。 abort 是抛异常触发错误处理。
  • 追问:404 怎么统一 JSON? 注册 app 级 404 errorhandler。
  • 追问:蓝图 404 为什么没生效? 路由匹配失败可能还没确定蓝图。
  • 追问:如何处理参数错误? 抛业务异常或 abort 400,统一转换。
  • 追问:生产能返回 traceback 吗? 不能,内部细节只进日志。

八、加强记忆

Flask 错误处理记成“abort 触发,errorhandler 接住,JSON 统一,日志留证”。4xx 是调用方问题,5xx 是服务端问题;用户看到克制信息,日志记录完整上下文。