mirror of https://github.com/pallets/flask.git
Corrected after response for error handlers
Before this change after request functions were not correctly invoked for error handlers.
This commit is contained in:
parent
dbcd64e2ee
commit
9cd32cac32
2
CHANGES
2
CHANGES
|
@ -15,6 +15,8 @@ Version 0.12
|
||||||
(pull request ``#1730``).
|
(pull request ``#1730``).
|
||||||
- Revert a behavior change that made the dev server crash instead of returning
|
- Revert a behavior change that made the dev server crash instead of returning
|
||||||
a Internal Server Error (pull request ``#2006``).
|
a Internal Server Error (pull request ``#2006``).
|
||||||
|
- Correctly invoke response handlers for both regular request dispatching as
|
||||||
|
well as error handlers.
|
||||||
|
|
||||||
Version 0.11.2
|
Version 0.11.2
|
||||||
--------------
|
--------------
|
||||||
|
|
29
flask/app.py
29
flask/app.py
|
@ -1555,7 +1555,7 @@ class Flask(_PackageBoundObject):
|
||||||
self.log_exception((exc_type, exc_value, tb))
|
self.log_exception((exc_type, exc_value, tb))
|
||||||
if handler is None:
|
if handler is None:
|
||||||
return InternalServerError()
|
return InternalServerError()
|
||||||
return handler(e)
|
return self.finalize_request(handler(e), from_error_handler=True)
|
||||||
|
|
||||||
def log_exception(self, exc_info):
|
def log_exception(self, exc_info):
|
||||||
"""Logs an exception. This is called by :meth:`handle_exception`
|
"""Logs an exception. This is called by :meth:`handle_exception`
|
||||||
|
@ -1623,9 +1623,30 @@ class Flask(_PackageBoundObject):
|
||||||
rv = self.dispatch_request()
|
rv = self.dispatch_request()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
rv = self.handle_user_exception(e)
|
rv = self.handle_user_exception(e)
|
||||||
|
return self.finalize_request(rv)
|
||||||
|
|
||||||
|
def finalize_request(self, rv, from_error_handler=False):
|
||||||
|
"""Given the return value from a view function this finalizes
|
||||||
|
the request by converting it into a repsonse and invoking the
|
||||||
|
postprocessing functions. This is invoked for both normal
|
||||||
|
request dispatching as well as error handlers.
|
||||||
|
|
||||||
|
Because this means that it might be called as a result of a
|
||||||
|
failure a special safe mode is available which can be enabled
|
||||||
|
with the `from_error_handler` flag. If enabled failures in
|
||||||
|
response processing will be logged and otherwise ignored.
|
||||||
|
|
||||||
|
:internal:
|
||||||
|
"""
|
||||||
response = self.make_response(rv)
|
response = self.make_response(rv)
|
||||||
response = self.process_response(response)
|
try:
|
||||||
request_finished.send(self, response=response)
|
response = self.process_response(response)
|
||||||
|
request_finished.send(self, response=response)
|
||||||
|
except Exception:
|
||||||
|
if not from_error_handler:
|
||||||
|
raise
|
||||||
|
self.logger.exception('Request finalizing failed with an '
|
||||||
|
'error while handling an error')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def try_trigger_before_first_request_functions(self):
|
def try_trigger_before_first_request_functions(self):
|
||||||
|
@ -1972,7 +1993,7 @@ class Flask(_PackageBoundObject):
|
||||||
response = self.full_dispatch_request()
|
response = self.full_dispatch_request()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error = e
|
error = e
|
||||||
response = self.make_response(self.handle_exception(e))
|
response = self.handle_exception(e)
|
||||||
return response(environ, start_response)
|
return response(environ, start_response)
|
||||||
finally:
|
finally:
|
||||||
if self.should_ignore_error(error):
|
if self.should_ignore_error(error):
|
||||||
|
|
|
@ -768,6 +768,29 @@ def test_error_handling():
|
||||||
assert b'forbidden' == rv.data
|
assert b'forbidden' == rv.data
|
||||||
|
|
||||||
|
|
||||||
|
def test_error_handling_processing():
|
||||||
|
app = flask.Flask(__name__)
|
||||||
|
app.config['LOGGER_HANDLER_POLICY'] = 'never'
|
||||||
|
|
||||||
|
@app.errorhandler(500)
|
||||||
|
def internal_server_error(e):
|
||||||
|
return 'internal server error', 500
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def broken_func():
|
||||||
|
1 // 0
|
||||||
|
|
||||||
|
@app.after_request
|
||||||
|
def after_request(resp):
|
||||||
|
resp.mimetype = 'text/x-special'
|
||||||
|
return resp
|
||||||
|
|
||||||
|
with app.test_client() as c:
|
||||||
|
resp = c.get('/')
|
||||||
|
assert resp.mimetype == 'text/x-special'
|
||||||
|
assert resp.data == b'internal server error'
|
||||||
|
|
||||||
|
|
||||||
def test_before_request_and_routing_errors():
|
def test_before_request_and_routing_errors():
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue