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

为Flask应用中返回JSON的API定制错误处理程序

在Flask中为API路由单独定制JSON格式的错误处理

嘿,这个需求我之前做项目的时候刚好碰到过,Flask其实提供了好几种灵活的方式来区分网站路由和API路由的错误处理,下面给你分享几个实用的方案:

方法1:通过请求路径快速判断(零改动现有路由)

如果你不想调整现有的路由结构,这个方法最直接——在全局错误处理函数里判断请求路径是否属于API,返回对应的响应格式:

from flask import jsonify, render_template, request

@app_instance.errorhandler(404)
def handle_404(err):
    # 检查请求路径是否以/api开头
    if request.path.startswith('/api'):
        return jsonify({
            'error': 'Not Found',
            'message': '请求的API接口不存在',
            'status_code': 404
        }), 404
    else:
        return render_template("err_404.html"), 404

@app_instance.errorhandler(500)
def handle_500(err):
    if request.path.startswith('/api'):
        # 记得加上你的数据库回滚逻辑
        db_instance.session.rollback()
        return jsonify({
            'error': 'Internal Server Error',
            'message': '服务器发生未知错误',
            'status_code': 500
        }), 500
    else:
        db_instance.session.rollback()
        return render_template("err_500.html"), 500

这个方案的优点是快速生效,不用改任何现有路由;缺点是如果后续API路径规则变化(比如不再以/api开头),你得同步修改判断条件。

方法2:用蓝图(Blueprint)分离API路由(推荐)

如果你的API路由数量较多,更推荐用蓝图把所有API路由统一管理,然后给蓝图单独注册错误处理——这样逻辑完全分离,后期维护起来特别方便:

第一步:创建API蓝图并注册路由

新建一个api.py文件,把所有API相关的内容放到这里:

# api.py
from flask import Blueprint, jsonify
from your_app_module import db_instance

# 创建API蓝图,指定url前缀为/api
api_bp = Blueprint('api', __name__, url_prefix='/api')

# 注册你的API路由
@api_bp.route('/user')
def get_user():
    # 你的API业务逻辑
    return jsonify({'data': 'user info'})

@api_bp.route('/weather')
def get_weather():
    # 你的API业务逻辑
    return jsonify({'data': 'weather info'})

# 给蓝图注册专属的错误处理
@api_bp.errorhandler(404)
def api_404(err):
    return jsonify({
        'error': 'Not Found',
        'message': 'API接口不存在',
        'status_code': 404
    }), 404

@api_bp.errorhandler(500)
def api_500(err):
    db_instance.session.rollback()
    return jsonify({
        'error': 'Internal Server Error',
        'message': '服务器内部错误',
        'status_code': 500
    }), 500

第二步:在主应用中注册蓝图

回到你的主应用文件(比如app.py),注册这个API蓝图:

# app.py
from flask import Flask, render_template
from api import api_bp
from your_db_module import db_instance

app_instance = Flask(__name__)
# 注册API蓝图
app_instance.register_blueprint(api_bp)

# 保留原来的网站路由错误处理
@app_instance.errorhandler(404)
def page_not_found_error(err):
    return render_template("err_404.html"), 404

@app_instance.errorhandler(500)
def internal_server_error(err):
    db_instance.session.rollback()
    return render_template("err_500.html"), 500

这样一来,所有/api开头的请求都会触发蓝图里的错误处理,返回JSON格式;网站路由则继续使用原来的HTML错误页面,完美实现了分离。

方法3:自定义请求标记(灵活适配复杂场景)

如果你的API路径规则不固定,或者需要更灵活的判断逻辑,可以用自定义装饰器给API路由打上标记,然后在错误处理里识别这个标记:

第一步:编写自定义装饰器

from flask import g

def mark_as_api(func):
    def wrapper(*args, **kwargs):
        # 在Flask的全局g对象中标记这个请求是API请求
        g.is_api_request = True
        return func(*args, **kwargs)
    return wrapper

第二步:给API路由添加装饰器

@app_instance.route('/api/user')
@mark_as_api
def api_user():
    return jsonify({'data': 'user info'})

@app_instance.route('/custom-api/weather')
@mark_as_api
def custom_api_weather():
    return jsonify({'data': 'weather info'})

第三步:修改全局错误处理

@app_instance.errorhandler(404)
def handle_404(err):
    # 检查g对象里的标记,默认是False
    if getattr(g, 'is_api_request', False):
        return jsonify({
            'error': 'Not Found',
            'message': '请求的API资源不存在',
            'status_code': 404
        }), 404
    else:
        return render_template("err_404.html"), 404

这个方案的优点是极度灵活,不管你的API路径是什么样的,只要加了@mark_as_api装饰器,就会返回JSON错误,特别适合路由规则复杂的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:28:31