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。
以下两种方式均可修复:
方式一:在请求处理中单独捕获异常
- 先从Flask导入
BadRequest异常:
from flask import Flask, jsonify, request, Response, BadRequest
- 修改
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
相关产品推荐
相关产品推荐

