hangar
hangar

Reputation: 1080

What status codes are raised internally by Flask?

I want to make sure my error responses are all valid JSON so my client can parse them. The Flask docs mention status codes 404 and 500 are raised internally, but I've seen some threads about how it can also return a 405. Is there a list of the codes that the Flask framework that I should handle?

I could simply go through and handle all the HTTP status codes, but that seems a bit heavy-handed for a Flask application.

@app.errorhandler(500)
def handle500error(error):
    return json.dumps(dict(error_message="A serious error occurred.")), 500

Alternately, is there a generic way to handle otherwise-unhandled errors?

Upvotes: 3

Views: 781

Answers (2)

Oleh Prypin
Oleh Prypin

Reputation: 34116

What I have for you is all places where HTTP exceptions are used in Flask and Werkzeug

$ ls
# We have source code of Flask and Werkzeug in the folder
flask-master  werkzeug-master

$ grep -oP "[A-Za-z]+(?=\(HTTPException\))" werkzeug-master/werkzeug/exceptions.py | paste -sd "|" -
# Get a list of HTTP exceptions
BadRequest|Unauthorized|Forbidden|NotFound|MethodNotAllowed|NotAcceptable|RequestTimeout|Conflict|Gone|LengthRequired|PreconditionFailed|RequestEntityTooLarge|RequestURITooLarge|UnsupportedMediaType|RequestedRangeNotSatisfiable|ExpectationFailed|ImATeapot|UnprocessableEntity|PreconditionRequired|TooManyRequests|RequestHeaderFieldsTooLarge|InternalServerError|NotImplemented|BadGateway|ServiceUnavailable|GatewayTimeout|HTTPVersionNotSupported

$ grep -Prn "\b(`!!`)\(" * | grep -Pv "/(tests|docs|examples)/|class "
# Search for these exceptions in source code, but exclude tests, docs, examples and definitions of those exception classes
flask-master/flask/wrappers.py:178:        raise BadRequest()
flask-master/flask/helpers.py:586:            raise NotFound()
flask-master/flask/helpers.py:590:        raise NotFound()
flask-master/flask/helpers.py:625:        raise NotFound()
flask-master/flask/app.py:1471:            return InternalServerError()
werkzeug-master/werkzeug/utils.py:504:                    raise BadRequest('The browser failed to transmit all '
werkzeug-master/werkzeug/exceptions.py:20:            raise NotFound()
werkzeug-master/werkzeug/serving.py:193:                execute(InternalServerError())
werkzeug-master/werkzeug/routing.py:1453:            raise MethodNotAllowed(valid_methods=list(have_match_for))
werkzeug-master/werkzeug/routing.py:1454:        raise NotFound()
werkzeug-master/werkzeug/formparser.py:185:            raise exceptions.RequestEntityTooLarge()
werkzeug-master/werkzeug/formparser.py:218:            raise exceptions.RequestEntityTooLarge()
werkzeug-master/werkzeug/formparser.py:359:        raise exceptions.RequestEntityTooLarge()
werkzeug-master/werkzeug/contrib/wrappers.py:56:            raise BadRequest('Not a JSON request')
werkzeug-master/werkzeug/contrib/wrappers.py:60:            raise BadRequest('Unable to read JSON request')
werkzeug-master/werkzeug/contrib/wrappers.py:82:            raise BadRequest('Not a Protobuf request')
werkzeug-master/werkzeug/contrib/wrappers.py:88:            raise BadRequest("Unable to parse Protobuf request")
werkzeug-master/werkzeug/contrib/wrappers.py:92:            raise BadRequest("Partial Protobuf request")

Upvotes: 1

Benoît Latinier
Benoît Latinier

Reputation: 2110

There is no way to do it easily with the decorator however there is an attribute in the app objects that is easier to manipulate: error_handler_spec

So a way to do what you want in a short way would be like that:

from functools import partial

def my_generic_handler(error, code=None):
    return json.dumps(dict(error_message="A serious error occurred.")), code

for code in range(400, 600):  # All error statuses. And even more but it's ok for the sake of this example
    app.error_handler_spec[None][code] = partial(my_generic_handler, code=code)

Here is what happens here. error_handler_spec is a dict for which the first level is the blueprint (None = the app) and the second level is the code or error to handle.

And partial is a tool that allow you to declare new functions from other ones be feeding only a part of the parameters. This way you can create a generic handler for all status codes and create the specific handlers on the fly.

Upvotes: 2

Related Questions