Permalink
Browse files

Backport from 1.1.x: A new attribute is available on request objects:

  exc_info.  Its value will be None until an exception is caught
  by the Pyramid router, after which it will be the result of
  sys.exc_info()
  • Loading branch information...
1 parent 6bc4d58 commit 09cfbe8e25becfbe6605a52847919491614ab984 @rockyburt rockyburt committed Aug 12, 2011
Showing with 30 additions and 3 deletions.
  1. +11 −0 CHANGES.txt
  2. +9 −1 pyramid/router.py
  3. +10 −2 pyramid/tests/test_router.py
View
@@ -1,3 +1,14 @@
+1.0.x (unreleased)
+==================
+
+Additions
+---------
+
+- Backport from 1.1.x: A new attribute is available on request objects:
+ ``exc_info``. Its value will be ``None`` until an exception is caught
+ by the Pyramid router, after which it will be the result of
+ ``sys.exc_info()``.
+
1.0 (2011-01-30)
================
View
@@ -1,3 +1,4 @@
+import sys
from zope.interface import implements
from zope.interface import providedBy
@@ -160,6 +161,7 @@ def __call__(self, environ, start_response):
# handle exceptions raised during root finding and view-exec
except Exception, why:
attrs['exception'] = why
+ attrs['exc_info'] = sys.exc_info()
for_ = (IExceptionViewClassifier,
request_iface.combined,
@@ -177,7 +179,13 @@ def __call__(self, environ, start_response):
# repoze.bfg.message docs-deprecated in Pyramid 1.0
environ['repoze.bfg.message'] = msg
- response = view_callable(why, request)
+ try:
+ response = view_callable(why, request)
+ finally:
+ if 'exc_info' in attrs:
+ del attrs['exc_info']
+ if 'exception' in attrs:
+ del attrs['exception']
# process the response
@@ -691,7 +691,14 @@ def test_call_view_raises_exception_view(self):
exception_response = DummyResponse()
exception_response.app_iter = ["Hello, world"]
view = DummyView(response, raise_exception=RuntimeError)
- exception_view = DummyView(exception_response)
+
+ class SimpleView(DummyView):
+ def __call__(self, context, request):
+ self.last_exception = getattr(request, 'exception', None)
+ self.last_exc_info = getattr(request, 'exc_info', None)
+ return DummyView.__call__(self, context, request)
+
+ exception_view = SimpleView(exception_response)
environ = self._makeEnviron()
self._registerView(view, '', IViewClassifier, IRequest, None)
self._registerView(exception_view, '', IExceptionViewClassifier,
@@ -700,7 +707,8 @@ def test_call_view_raises_exception_view(self):
start_response = DummyStartResponse()
result = router(environ, start_response)
self.assertEqual(result, ["Hello, world"])
- self.assertEqual(view.request.exception.__class__, RuntimeError)
+ self.assertEqual(exception_view.last_exception.__class__, RuntimeError)
+ self.assertTrue(exception_view.last_exc_info is not None)
def test_call_view_raises_super_exception_sub_exception_view(self):
from pyramid.interfaces import IViewClassifier

0 comments on commit 09cfbe8

Please sign in to comment.