Fixed request context preservation and teardown handler interaction.

This commit is contained in:
Armin Ronacher 2013-06-02 21:47:28 +01:00
parent 6dfe933260
commit 1b40b3b573
4 changed files with 59 additions and 1 deletions

View file

@ -235,6 +235,10 @@ class RequestContext(object):
# is pushed the preserved context is popped.
self.preserved = False
# remembers the exception for pop if there is one in case the context
# preservation kicks in.
self._preserved_exc = None
# Functions that should be executed after the request on the response
# object. These will be called before the regular "after_request"
# functions.
@ -296,7 +300,7 @@ class RequestContext(object):
# functionality is not active in production environments.
top = _request_ctx_stack.top
if top is not None and top.preserved:
top.pop()
top.pop(top._preserved_exc)
# Before we push the request context we have to ensure that there
# is an application context.
@ -331,9 +335,18 @@ class RequestContext(object):
clear_request = False
if not self._implicit_app_ctx_stack:
self.preserved = False
self._preserved_exc = None
if exc is None:
exc = sys.exc_info()[1]
self.app.do_teardown_request(exc)
# If this interpreter supports clearing the exception information
# we do that now. This will only go into effect on Python 2.x,
# on 3.x it disappears automatically at the end of the exception
# stack.
if hasattr(sys, 'exc_clear'):
sys.exc_clear()
request_close = getattr(self.request, 'close', None)
if request_close is not None:
request_close()
@ -356,6 +369,7 @@ class RequestContext(object):
if self.request.environ.get('flask._preserve_context') or \
(exc is not None and self.app.preserve_context_on_exception):
self.preserved = True
self._preserved_exc = exc
else:
self.pop(exc)