Different error responses based on DEBUG flag
See original GitHub issueNot sure if this is a bug or a gap in my understanding (I am very new to Flask, and Python in general).
Since I felt constrained by the dict-based error handling in Flask-Restful, I used the ‘errorhandler’ decorator provided by Flask. The issue is, the errorhandlers work fine when DEBUG=True (and show custom error responses that I have set up), but show a cryptic {'message': 'Internal Server Error'}
when DEBUG=False.
After a lot of struggle, I figured out that it was due to 2 reasons:
- The PROPAGATE_ERRORS flag being set and unset on DEBUG=True/False.
- This snippet of code in the
flask_restful/__init__.py
file:
if not isinstance(e, HTTPException) and current_app.propagate_exceptions:
exc_type, exc_value, tb = sys.exc_info()
if exc_value is e:
raise
else:
raise e
headers = Headers()
if isinstance(e, HTTPException):
code = e.code
default_data = {
'message': getattr(e, 'description', http_status_message(code))
}
headers = e.get_response().headers
else:
code = 500
default_data = {
'message': http_status_message(code),
}
which raises the exception and lets the flask errorhandler deal with it if propagate_exceptions is True, but handles the exception by itself if otherwise.
I have 2 suggestions:
- You should mention in the documentation that Flask-Restful overrides the default Flask error handlers.
- Since you are overriding the error handlers, should you even care whether propagate_exceptions is True or False?
It looks weird to me that flask_restful handles error responses differently based on the DEBUG flag. Is there a way I can disable FR error handling? Is there a flexible error handing option in FR so that I can avoid the Flask errorhandler ?
Issue Analytics
- State:
- Created 7 years ago
- Reactions:6
- Comments:8
Top GitHub Comments
If debug mode is disabled, the
PROPAGATE_EXCEPTIONS
setting can still be set to True explicitly:The workaround in #280 also works, but does so by completely bypassing flask_restful error handling which I think is a bit of a blunt solution.
Setting
PROPAGATE_EXCEPTIONS = True
also works, but is a bad solution. When flask_restful is initialised with a flask app, it hijacks Flask’s native error handler functions -app.handle_user_exception
andapp.handle_exception
.When
PROPAGATE_EXCEPTIONS = True
, flask_restful will forego it’s own error handler, and fall back to these original flaskapp.handle_user_exception
andapp.handle_exception
implementations. This means you can either use flask errorhandlers OR flask_restful’s error handler (you might want both).What these original Flask error handler functions do is check to see if there is a defined custom handler for that given error (a function decorated by
@app.errorhandler
) and let that function handle the error - which is what we want. Hence why settingPROPAGATE_EXCEPTIONS = True
makes@app.errorhandler
functions work.The problem with this is that Flask also does something with
PROPAGATE_EXCEPTIONS
. In Flask when this isTrue
and there is no defined handler for the error, it will reraise the exception instead of returning a stockwerkzeug.exceptions.InternalServerError
when the flag isFalse
. This is bad because this single flag does 2 distinct but deceptively similar things, and there is no way to do one, and not the other.I propose:
USE_FLASK_ERROR_HANDLER
perhaps.Thoughts? Happy to open a PR with these changes.