티스토리 뷰
PROPAGATE_EXCEPTIONS는 flask config option으로 default 는 None이고 DEBUG가 True면 True로 setting된다.
flask_restful/__init__.py를 보면 이렇게 구현되어 있다.
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),
}
PROPAGATE_EXCEPTIONS가 set일 때, flask-restful의 handler가 있다면 처리하고 그렇지 않다면 flask로 던져서 flask의 handler가 처리한다.
PROPAGATE_EXCEPTIONS가 unset일 땐, flask-restful의 handler가 없더라도 flask로 던져서 처리하지 않고 바로 error message를 만들어 반환한다.
(잘 이해는 안되지만 언젠간 되겠지..)
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 and app.handle_exception.
When PROPAGATE_EXCEPTIONS = True, flask_restful will forego it's own error handler, and fall back to these original flask app.handle_user_exception and app.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 setting PROPAGATE_EXCEPTIONS = True makes @app.errorhandler functions work.
The problem with this is that Flask also does something with PROPAGATE_EXCEPTIONS. In Flask when this is True and there is no defined handler for the error, it will reraise the exception instead of returning a stock werkzeug.exceptions.InternalServerError when the flag is False. 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:
- The flask_restful error handler should check if there is a flask error handler for the given error and use that.
- Additionally if we actually want to forego the flask_restful error handler, flask_restful should do so using a different config flag value. Something like USE_FLASK_ERROR_HANDLER perhaps.
'Python' 카테고리의 다른 글
os.path vs pathlib (0) | 2021.08.11 |
---|---|
WSGI (0) | 2021.03.10 |