summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-07-13 00:41:59 -0400
committerChris McDonough <chrism@plope.com>2011-07-13 00:41:59 -0400
commitd05117e9655e3619e66bfef86f40043fbcc61829 (patch)
tree23d76eb5b6d59552289b31ef28303d0c1934f83c
parent60bc3075c005984969f60eb3b768ce7214135514 (diff)
downloadpyramid-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.txt4
-rw-r--r--TODO.txt6
-rw-r--r--pyramid/router.py6
-rw-r--r--pyramid/tests/test_router.py27
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
-------------
diff --git a/TODO.txt b/TODO.txt
index 84bd14153..56fd89584 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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