21

A consumer of my REST API says that on occasion I am returning a 400 Bad Request - The request sent by the client was syntactically incorrect. error.

My application (Python/Flask) logs don't seem to be capturing this, and neither do my webserver/Nginx logs.

Edit: I would like to try to cause a 400 bad request in Flask for debugging purposes. How can I do this?

Following James advice, I added something similar to the following:

@app.route('/badrequest400')
def bad_request():
    return abort(400)

When I call this, flask returns the following HTML, which doesn't use the "The request sent by the client was syntactically incorrect" line:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>400 Bad Request</title>
<h1>Bad Request</h1>
<p>The browser (or proxy) sent a request that this server could not understand.</p>

(I'm not sure why it isn't including the <body> tags.

It appears to me that there are different variations of the 400 error message. For example, if I set a cookie to a value of length 50,000 (using Interceptor with Postman), I'll get the following error from Flask instead:

<html>
<head>
    <title>Bad Request</title>
</head>
<body>
    <h1>
        <p>Bad Request</p>
    </h1>
Error parsing headers: 'limit request headers fields size'

</body>
</html>

Is there a way to get Flask to through the different variations of 400 errors?

Matthew Moisen
  • 16,701
  • 27
  • 128
  • 231

4 Answers4

25

you can return the status code as a second parameter of the return, see example below

@app.route('/my400')
def my400():
    code = 400
    msg = 'my message'
    return msg, code
John
  • 4,786
  • 8
  • 35
  • 44
  • 1
    Also good to note that the status module contains the standard HTTP statuses. `from flask_api import status` and then simply `status.HTTP_200_OK` – VSZM Nov 24 '18 at 19:55
18

You can use abort to raise an HTTP error by status code.

from flask import abort
@app.route('/badrequest400')
def bad_request():
    abort(400)
davidism
  • 121,510
  • 29
  • 395
  • 339
James Scholes
  • 7,686
  • 3
  • 19
  • 20
  • Hi James, thanks for the idea. However, when I do this, Flask by default returns the following description under 400 Bad Request: `The browser (or proxy) sent a request that this server could not understand.`. It looks like there are different types of 400 error messages -- for example, If I create add cookie with 50000 characters, it fails with a 400 but the description says that its an invalid header. Any idea on how to trigger the "syntacticlaly incorrect" version of the 400? – Matthew Moisen Sep 02 '15 at 23:32
  • Hey James, do you have any thoughts about my comment and updated question? – Matthew Moisen Jan 26 '16 at 23:21
  • Wish I could also return custom message with status code. – Kishor Pawar Sep 20 '16 at 11:11
13

You can also use abort with custom message error:

from flask import abort
abort(400, 'My custom message')

See https://flask-restplus.readthedocs.io/en/stable/errors.html

Xtonev
  • 131
  • 1
  • 2
2

Also, You can use jsonify

from flask import jsonify

class SomeView(MethodView):
    def post(self, *args, **kwargs):
        if "csv_file" not in request.files:
            return jsonify({'errors': 'No csv_file key in request.files.'}), 400
hernan
  • 383
  • 3
  • 8