Flask REST API请求头错误自定义异常及POST接口问题
Great work getting your Flask REST API integrated with your SQL database—your current GET/POST implementation is solid, especially using parameterized queries to prevent SQL injection! Let's walk through adding custom exception handling for request header errors, which will make your API more robust and give clear feedback during testing in Postman/RESTClient.
Step 1: Create a Custom Exception Class
First, define a custom exception to represent request header-related issues. This lets you carry specific error messages and appropriate HTTP status codes:
from flask import Flask, request, Response, json # Make sure your DateTimeEncoder is imported here too # Custom exception for request header errors class RequestHeaderError(Exception): def __init__(self, message, status_code=400): super().__init__(message) self.message = message self.status_code = status_code
Step 2: Register an Error Handler for the Exception
Next, tell Flask how to handle this exception by registering an error handler. This ensures all instances of RequestHeaderError return a consistent JSON-formatted response:
@app.errorhandler(RequestHeaderError) def handle_request_header_error(error): error_response = json.dumps({"error": error.message}) return Response( error_response, status=error.status_code, mimetype="application/json" ) # Bonus: Add a general exception handler to standardize other errors @app.errorhandler(Exception) def handle_general_exception(error): error_response = json.dumps({"error": str(error)}) return Response( error_response, status=500, mimetype="application/json" )
Step 3: Add Request Header Checks in Your View
Now update your subscribe endpoint to validate the request headers before processing the POST request. For example, since you're using request.form.get to fetch form data, you should check that the Content-Type header is set to application/x-www-form-urlencoded:
@app.route('/api/subscribe/', methods=['GET', 'POST']) def subscribe(): if request.method == 'GET': try: data = DB.get_subscription_list() return Response( json.dumps({'result': data}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json' ) except Exception as e: raise e # Let the general handler format the response elif request.method == 'POST': # Validate Content-Type header expected_content_type = "application/x-www-form-urlencoded" content_type = request.headers.get("Content-Type") if not content_type or expected_content_type not in content_type: raise RequestHeaderError( f"Invalid Content-Type. Expected: {expected_content_type}", status_code=415 # 415 = Unsupported Media Type ) try: email = request.form.get('email') # Optional: Validate that email was provided if not email: raise RequestHeaderError("Email parameter is required", status_code=400) DB.add_email(email) # Use 201 Created status code for successful resource creation return Response( json.dumps({'result': 'Email added to database'}, cls=DateTimeEncoder, sort_keys=True), mimetype='application/json', status=201 ) except Exception as e: raise e
Step 4: Test in Postman/RESTClient
- Test invalid Content-Type: Set the request's
Content-Typeto something likeapplication/jsoninstead ofapplication/x-www-form-urlencoded—you'll get a 415 response with your custom error message. - Test missing email parameter: Submit a POST request without the
emailform field—you'll get a 400 response indicating the missing parameter. - Test valid request: Everything should work as before, but now with cleaner, consistent error responses.
A few extra notes:
- Using
raise einstead ofreturn elets your exception handlers take care of formatting responses, keeping your view code clean. - Using appropriate HTTP status codes (like 415 for unsupported media type, 400 for bad request) makes your API more REST-compliant.
内容的提问来源于stack exchange,提问作者amanb

