简体   繁体   中英

how to catch all exceptions raised in flask_restful app

I do have simple restful app with Flask-Restful

from flask import Flask
from flask_restful import Api

app = Flask(__name__)
...
api = Api(app)

api.add_resource(ContactList, "/contacts")


if __name__ == '__main__':
    from object_SQLAlchemy import db
    db.init_app(app)
    app.run(port=5000)


class Contact(Resource):
    parser = reqparse.RequestParser()
    parser.add_argument(
        'contact_no',
        type=str,
        required=True,
        help="This field cannot be left blank"
    )

    @throttling.Throttle("10/m", strategy=2)
    def get(self, name):
        contact = Contacts.findbyname(name)
        if contact:
            return contact.json()
        return {"message": "Contact does not exist."}, 404

'get' method is decorated with my implementation of throttling ( https://github.com/scgbckbone/RESTAPI/blob/master/resources/utils/throttling.py ). What is important is that the throttling decorator raises exceptions on some occasions - most importantly when limit is reached. I would like to be able to catch that exception and return some reasonable json message.

But none of following works:

from ..app_alchemy import api, app


@api.errorhandler(Exception)
def handle_error(e):
    return {"error": str(e)}


@app.errorhandler(500)
def handle_error_app(e):
    return {"error": str(e.args[0])}


@app.handle_exception(Exception)
def handle_it_app(e):
    return {"error": str(e.args[0])}


@api.handle_exception(Exception)
def handle_it(e):
   return {"error": str(e.args[0])}

I'm still getting back default message

{"message": "Internal Server Error"}

Do I use errorhandlers correctly, or is the issue related to the use of decorator? I truly have no idea.

There is a Flask-Restful built-in tool for handling exceptions, you can pass a dictionary of exception classes and response fields to Api constructor:

api = Api(app, errors={
    'Exception': {
        'status': 400,
        'message': 'bad_request',
        'some_description': 'Something wrong with request'
    }
})

Status is 500 by default, all other field are just turned to JSON and sent in response.

There is a major downside: you cannot use exception text as error message. There is an open issue for it.

Sentry is a great tool for catching exceptions across different platforms and frameworks {Including Python, Django and Flask}. This example give pointers on you can integrate it with your Flask application.

I've used it in production, the feature I liked the most is that it captures context of the error, including Operating System, Browser Version etc along with other information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM