Browse Source

Invoke after_request on exceptions as well. This fixes #59

pull/124/head
Armin Ronacher 15 years ago
parent
commit
33e7f2b990
  1. 13
      flask.py
  2. 32
      tests/flask_tests.py

13
flask.py

@ -1362,6 +1362,12 @@ class Flask(_PackageBoundObject):
Then you still have the original application object around and
can continue to call methods on it.
.. versionchanged:: 0.4
The :meth:`after_request` functions are now called even if an
error handler took over request processing. This ensures that
even if an exception happens database have the chance to
properly close the connection.
:param environ: a WSGI environment
:param start_response: a callable accepting a status code,
a list of headers and an optional
@ -1376,6 +1382,13 @@ class Flask(_PackageBoundObject):
response = self.process_response(response)
except Exception, e:
response = self.make_response(self.handle_exception(e))
try:
response = self.process_response(response)
except Exception, e:
self.logger.exception('after_request handler failed '
'to postprocess error response. '
'Depending on uncertain state?')
return response(environ, start_response)
def request_context(self, environ):

32
tests/flask_tests.py

@ -16,6 +16,7 @@ import sys
import flask
import unittest
import tempfile
from logging import StreamHandler
from contextlib import contextmanager
from datetime import datetime
from werkzeug import parse_date, parse_options_header
@ -240,6 +241,37 @@ class BasicFunctionalityTestCase(unittest.TestCase):
assert 'after' in evts
assert rv == 'request|after'
def test_after_request_errors(self):
app = flask.Flask(__name__)
called = []
@app.after_request
def after_request(response):
called.append(True)
return response
@app.route('/')
def fails():
1/0
rv = app.test_client().get('/')
assert rv.status_code == 500
assert 'Internal Server Error' in rv.data
assert len(called) == 1
def test_after_request_handler_error(self):
error_out = StringIO()
app = flask.Flask(__name__)
app.logger.addHandler(StreamHandler(error_out))
@app.after_request
def after_request(response):
1/0
return response
@app.route('/')
def fails():
1/0
rv = app.test_client().get('/')
assert rv.status_code == 500
assert 'Internal Server Error' in rv.data
assert 'after_request handler failed' in error_out.getvalue()
def test_error_handling(self):
app = flask.Flask(__name__)
@app.errorhandler(404)

Loading…
Cancel
Save