Why is my Flask error handler not being called?
Referring to both this question, and the docs, the key piece of information I took from both is if your route is a Flask-RESTful one, which yours is, it will be handled by handle_error()
, and the only way to prevent or customise this is to implement your own API class, and override handle_error()
.
Following up on @dylanj.nz's answer, this vanilla-Flask error handling method, and this example of overriding Flask-RESTful's API , here's the method I settled on. It allows Flask-RESTful to handle HTTPException
types of exceptions, but passes everything else through to the default (Flask) handler, where custom error messages can be specified (an entire JSON object of key/value entries, if you want) at the time of the exception.
from flask_restful import Resource, Api as _Api, HTTPExceptionapp = Flask(__name__)# This new Exception will accept a message, a status code, and a# payload of other values to be displayed as a JSON objectclass FlaskGenericException(Exception): status_code = 500 # default unless overridden def __init__(self, message, status_code=None, payload=None): Exception.__init__(self) self.message = message if status_code is not None: self.status_code = status_code self.payload = payload def to_dict(self): rv = dict(self.payload or ()) rv['message'] = self.message return rv@app.errorhandler(FlaskGenericException)def handle_flask_generic_error(error): response = jsonify(error.to_dict()) response.status_code = error.status_code return response# This overridden Flask-RESTful API class will keep Flask-RESTful# from handling errors other than HTTPException ones.class Api(_Api): def error_router(self, original_handler, e): # Override original error_router to only handle HTTPExceptions. if self._has_fr_route() and isinstance(e, HTTPException): try: # Use Flask-RESTful's error handling method return self.handle_error(e) except Exception: # Fall through to original handler (i.e. Flask) pass return original_handler(e)api = Api(app)class TestMe(Resource): def get(self): try: ldapc = ldap.connection except: # message = first parameter. Other parameters come in as "payload" raise FlaskGenericException('A generic error', status_code=505, payload={'user': 'John Doe', 'company': 'Foobar Corp.'})api.add_resource(TestMe, '/testme', endpoint='TestMe')