=== modified file 'oops_wsgi/middleware.py'
--- oops_wsgi/middleware.py 2011-08-18 00:45:58 +0000
+++ oops_wsgi/middleware.py 2011-08-22 07:04:24 +0000
@@ -85,8 +85,23 @@ state['write'] = start_response(status, headers) write = state['write'] write(bytes)
- def oops_start_response(status, headers):
- state['response'] = (status, headers)
+ def oops_start_response(status, headers, exc_info=None):
+ if exc_info is not None:
+ # The app is explicitly signalling an error (rather than
+ # returning a page describing the error). Capture that and then
+ # forward to the containing element verbatim. In future we might
+ # choose to add the OOPS id to the headers (but we can't fiddle
+ # the body as it is being generated by the contained app.
+ report = config.create(
+ dict(exc_info=exc_info, url=construct_url(environ)))
Careful! You seem to be indenting by 8 instead of 4.
@@ -52,7 +53,21 @@ environ['HTTP_HOST'] = 'example.com' environ['PATH_INFO'] = '/demo' environ['QUERY_STRING'] = 'param=value'
- def start_response(status, headers):
+ def start_response(status, headers, exc_info=None):
+ if exc_info:
+ # If an exception is raised after we have written (via the app
+ # calling our oops_write) or after we have yielded data, we
+ # must supply exc_info in the call to start_response, per the
+ # wsgi spec. The easiest way to do that is to always supply
+ # exc_info when reporting an exception - that will DTRT if
+ # start_response upstream had already written data. Thus
+ # our test start_response which lives above the oops middleware
+ # captures the fact exc_info was called and all our tests that
+ # expect oopses raised expect the exc_info to be present.
+ self.calls.append(
+ ('start error', status, headers, exc_info[0],
+ exc_info[1].args))
Here too, indentation goes too far. You're not getting tabs, are you?
@@ -191,7 +206,8 @@ 'url': 'http://example.com/demo?param=value', 'value': u'boom, yo'},
# Then the middleware responses
- ('500 Internal Server Error', [('Content-Type', 'text/html')]),
+ ('start error', '500 Internal Server Error',
+ [('Content-Type', 'text/html')], ValueError, ('boom, yo',)),
Horrid layout. Your branch didn't start it, so I won't insist that you fix it. But take my review with a grain of salt since I can't really make sense of this in reasonable time.
In this case though, please do fix the layout! So far the best solution I've found is to move the expected dict into a variable. Not great, but better than any of the alternatives I'm aware of.
Generally good, but a few notes:
=== modified file 'oops_wsgi/ middleware. py' middleware. py 2011-08-18 00:45:58 +0000 middleware. py 2011-08-22 07:04:24 +0000
state[ 'write' ] = start_response( status, headers)
write = state['write']
write( bytes) response( status, headers): response( status, headers, exc_info=None): info=exc_ info, url=construct_ url(environ) ))
--- oops_wsgi/
+++ oops_wsgi/
@@ -85,8 +85,23 @@
- def oops_start_
- state['response'] = (status, headers)
+ def oops_start_
+ if exc_info is not None:
+ # The app is explicitly signalling an error (rather than
+ # returning a page describing the error). Capture that and then
+ # forward to the containing element verbatim. In future we might
+ # choose to add the OOPS id to the headers (but we can't fiddle
+ # the body as it is being generated by the contained app.
+ report = config.create(
+ dict(exc_
Careful! You seem to be indenting by 8 instead of 4.
+ ids = config. publish( report) status, headers, exc_info)
+ try:
+ state['write'] = start_response(
+ return state['write']
+ finally:
+ del exc_info
Out of interest, whence the del?
=== modified file 'oops_wsgi/ tests/test_ middleware. py' tests/test_ middleware. py 2011-08-18 22:44:58 +0000 tests/test_ middleware. py 2011-08-22 07:04:24 +0000
--- oops_wsgi/
+++ oops_wsgi/
@@ -52,7 +53,21 @@
environ[ 'HTTP_HOST' ] = 'example.com'
environ[ 'PATH_INFO' ] = '/demo'
environ[ 'QUERY_ STRING' ] = 'param=value' status, headers): status, headers, exc_info=None):
- def start_response(
+ def start_response(
+ if exc_info:
+ # If an exception is raised after we have written (via the app
+ # calling our oops_write) or after we have yielded data, we
+ # must supply exc_info in the call to start_response, per the
+ # wsgi spec. The easiest way to do that is to always supply
+ # exc_info when reporting an exception - that will DTRT if
+ # start_response upstream had already written data. Thus
+ # our test start_response which lives above the oops middleware
+ # captures the fact exc_info was called and all our tests that
+ # expect oopses raised expect the exc_info to be present.
+ self.calls.append(
+ ('start error', status, headers, exc_info[0],
+ exc_info[1].args))
Here too, indentation goes too far. You're not getting tabs, are you?
@@ -191,7 +206,8 @@
'url': 'http:// example. com/demo? param=value',
'value' : u'boom, yo'},
# Then the middleware responses
- ('500 Internal Server Error', [('Content-Type', 'text/html')]),
+ ('start error', '500 Internal Server Error',
+ [('Content-Type', 'text/html')], ValueError, ('boom, yo',)),
Horrid layout. Your branch didn't start it, so I won't insist that you fix it. But take my review with a grain of salt since I can't really make sense of this in reasonable time.
@@ -250,3 +268,20 @@
self. wrap_and_ run(inner, config)
self. assertEqual( 'http:// example. com/demo? param=value',
self. calls[0] ['url'] ) response_ with_just_ exc_info_ generates_ oops(self) : for_oopsing( ) and_run( inner, config) l([{'id' : 1, example. com/demo? param=value',
+
+ def test_start_
+ def inner(environ, start_response):
+ try:
+ raise ValueError('boom, yo')
+ except ValueError:
+ exc_info = sys.exc_info()
+ start_response('500 FAIL', [], exc_info)
+ yield 'body'
+ config = self.config_
+ self.wrap_
+ self.assertEqua
+ 'type': 'ValueError',
+ 'url': 'http://
+ 'value': u'boom, yo'},
+ ('start error', '500 FAIL', [], ValueError, ('boom, yo',))],
+ self.calls)
In this case though, please do fix the layout! So far the best solution I've found is to move the expected dict into a variable. Not great, but better than any of the alternatives I'm aware of.
Jeroen