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

Flask API如何处理POST空请求体并返回400状态码

问题描述

我想在Flask API中添加一个错误处理器,当POST请求的请求体为空时,返回JSON格式的400错误信息,并且Postman中显示状态码为400 Bad Request。但现在的情况是,响应体里能看到400错误信息,可Postman上显示的状态码却是500。

现有代码
import pyodbc
from pytz import timezone
from flask import Flask, jsonify, request, Response
from datetime import datetime, timedelta
from waitress import serve
from flask_api import status

app = Flask(__name__)

server = 'bla'
database = 'bla'
username = 'bla'
password = 'bla'
driver = '{ODBC Driver 18 for SQL Server}'

connection_string = 'DRIVER='+driver+';SERVER=tcp:'+server + \
    ';PORT=bla;DATABASE='+database+';UID='+username+';PWD=' + password


def hello(data):

    try:
        
        if data["url"] == "":
            return jsonify({"message": "Error Code : 404 - Not found"}), status.HTTP_404_NOT_FOUND
        
               
        Headers = {"Content-Type": "application/json",
                   "Authorization": "Bearer " + access_token}

        resp = requests.post(
            data["url"], json=bla, headers=Headers)

        if resp.status_code == 200:

            values = resp.json()["value"]

            {perform some operation here}
            
            return filtered_values, status.HTTP_200_OK

        else:
            return resp.json()["error"]["message"],resp.status_code
    except Exception as e:
        print("Error", e)
        raise
    

@app.route("/")
def status():
    return jsonify({"status": "OK"}), status.HTTP_200_OK


@app.errorhandler(404)
def not_found(e):
    return jsonify({"message": str(e)}), status.HTTP_404_NOT_FOUND


@app.route("/somepath", methods=["GET", "POST"])
def details():
    if request.method == "POST":
        try:

            operation_data = request.get_json()

            
            data, code = hello(operation_data )

            if code != 200:
                return jsonify({"message": str(data)}), code

            else:
                if len(data) != 0 and data is not None:

                    conn = pyodbc.connect(connection_string)
                    cursor = conn.cursor()
                    
                    for d in data:
                        
                        cursor.execute(some query)

                    conn.commit()
                    cursor.close()
                    conn.close()
                    new_resp = jsonify({"message": "successful"})
                    return new_resp, status.HTTP_200_OK

                else:
                    new_resp = jsonify({"message": "nothing to do"})
                    return new_resp, status.HTTP_200_OK

        except Exception as exception:
            print(exception)
            return jsonify(str(exception)), status.HTTP_500_INTERNAL_SERVER_ERROR

    else:
        return jsonify({"status": str(request.method) + " - Method not allowed"}),status.HTTP_405_METHOD_NOT_ALLOWED

   
if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8000, debug=True)
    # serve(app, listen='*:8000')
解决方案

问题根源:当POST请求体为空时,request.get_json()会抛出BadRequest异常(无法解析JSON),这个异常被外层的Exception捕获后直接返回了500状态码,而非预期的400。

以下两种方式均可修复:

方式一:在请求处理中单独捕获异常

  1. 先从Flask导入BadRequest异常:
from flask import Flask, jsonify, request, Response, BadRequest
  1. 修改details函数的异常捕获逻辑:
@app.route("/somepath", methods=["GET", "POST"])
def details():
    if request.method == "POST":
        try:
            operation_data = request.get_json()
            # 额外判断:若解析后请求体为空,返回400
            if not operation_data:
                return jsonify({"message": "请求体不能为空"}), status.HTTP_400_BAD_REQUEST
            
            data, code = hello(operation_data )

            if code != 200:
                return jsonify({"message": str(data)}), code

            else:
                if len(data) != 0 and data is not None:

                    conn = pyodbc.connect(connection_string)
                    cursor = conn.cursor()
                    
                    for d in data:
                        
                        cursor.execute(some query)

                    conn.commit()
                    cursor.close()
                    conn.close()
                    new_resp = jsonify({"message": "successful"})
                    return new_resp, status.HTTP_200_OK

                else:
                    new_resp = jsonify({"message": "nothing to do"})
                    return new_resp, status.HTTP_200_OK

        except BadRequest as e:
            # 捕获JSON解析失败(如空请求体)的情况
            return jsonify({"message": "无效的JSON格式或请求体为空"}), status.HTTP_400_BAD_REQUEST
        except Exception as exception:
            print(exception)
            return jsonify(str(exception)), status.HTTP_500_INTERNAL_SERVER_ERROR

    else:
        return jsonify({"status": str(request.method) + " - Method not allowed"}),status.HTTP_405_METHOD_NOT_ALLOWED

方式二:添加全局400错误处理器

注册全局错误处理器,统一处理所有400类型的错误:

@app.errorhandler(400)
def bad_request(e):
    return jsonify({"message": "无效的请求:请求体为空或JSON格式错误"}), status.HTTP_400_BAD_REQUEST

两种方式都能让空请求体的POST请求返回400状态码及对应JSON错误信息,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:50:43