Search code examples
pythonflaskpython-decoratorsendpoint

Handle all exceptions in Flask route


I have a simple route in my Flask app:

@app.route('/', methods=['GET'])
def homepage():
    return '{}'.format(1 / 0)

When the user visits site.com/ she should see the result of 1/0. Of course that's not possible, so Python throws me an error.

Now, I would like all errors across all my endpoints to be handled in a special way: I would like them to return a JSON response, like:

{
    'status_code': 500,
    'status': 'Internal Server Error'
}

I wrote a decorator to do exactly this:

def return_500_if_errors(f):
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except:
            response = {
                'status_code': 500,
                'status': 'Internal Server Error'
            }
            return flask.jsonify(response), 500
    return wrapper

I then added the decorator to the endpoint:

@return_500_if_errors
@app.route('/', methods=['GET'])
def homepage():
    return '{}'.format.(1 / 0)

However, the decorator seems to have no effect.


Solution

  • As noted by both @YiFei and @Joost, the issue was with the decorators order.

    This does indeed work:

    def return_500_if_errors(f):
        def wrapper(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except:
                response = {
                    'status_code': 500,
                    'status': 'Internal Server Error'
                }
                return flask.jsonify(response), 500
        return wrapper
    
    @app.route('/', methods=['GET'])
    @return_500_if_errors
    def homepage():
        return '{}'.format.(1 / 0)
    

    @Joost's answer is similar but somehow different as there it's the error itself to be captured and returned - rather than a standardized JSON.