diff options
| author | Chris McDonough <chrism@plope.com> | 2011-07-13 00:41:59 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-07-13 00:41:59 -0400 |
| commit | d05117e9655e3619e66bfef86f40043fbcc61829 (patch) | |
| tree | 23d76eb5b6d59552289b31ef28303d0c1934f83c | |
| parent | 60bc3075c005984969f60eb3b768ce7214135514 (diff) | |
| download | pyramid-d05117e9655e3619e66bfef86f40043fbcc61829.tar.gz pyramid-d05117e9655e3619e66bfef86f40043fbcc61829.tar.bz2 pyramid-d05117e9655e3619e66bfef86f40043fbcc61829.zip | |
- We now clear ``request.response`` before we invoke an exception view; an
exception view will be working with a request.response that has not been
touched by any code prior to the exception.
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | TODO.txt | 6 | ||||
| -rw-r--r-- | pyramid/router.py | 6 | ||||
| -rw-r--r-- | pyramid/tests/test_router.py | 27 |
4 files changed, 37 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index ea83827cc..21bea6572 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -45,6 +45,10 @@ Bug Fixes inappropriately used ``DBSession.rollback()`` instead of ``transaction.abort()`` in one place. +- We now clear ``request.response`` before we invoke an exception view; an + exception view will be working with a request.response that has not been + touched by any code prior to the exception. + Documentation ------------- @@ -1,12 +1,6 @@ Pyramid TODOs ============= -Must-Have ---------- - -- Investigate whether we should replace request.response before we invoke an - exception view. - Should-Have ----------- diff --git a/pyramid/router.py b/pyramid/router.py index 880429424..0a92b5cd5 100644 --- a/pyramid/router.py +++ b/pyramid/router.py @@ -162,6 +162,12 @@ class Router(object): # handle exceptions raised during root finding and view-exec except Exception, why: + # clear old generated request.response, if any; it may + # have been mutated by the view, and its state is not + # sane (e.g. caching headers) + if 'response' in attrs: + del attrs['response'] + attrs['exception'] = why for_ = (IExceptionViewClassifier, diff --git a/pyramid/tests/test_router.py b/pyramid/tests/test_router.py index af311cfc2..6cd86901e 100644 --- a/pyramid/tests/test_router.py +++ b/pyramid/tests/test_router.py @@ -403,6 +403,33 @@ class TestRouter(unittest.TestCase): why = exc_raised(HTTPNotFound, router, environ, start_response) self.assertEqual(why[0], 'notfound') + def test_call_view_raises_response_cleared(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from pyramid.interfaces import IExceptionViewClassifier + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + def view(context, request): + request.response.a = 1 + raise KeyError + def exc_view(context, request): + self.failIf(hasattr(request.response, 'a')) + request.response.body = 'OK' + return request.response + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + self._registerView(exc_view, '', IExceptionViewClassifier, + IRequest, KeyError) + router = self._makeOne() + start_response = DummyStartResponse() + itera = router(environ, start_response) + self.assertEqual(itera, ['OK']) + def test_call_request_has_response_callbacks(self): from zope.interface import Interface from zope.interface import directlyProvides |
