[Checkins] SVN: bobo/branches/patrick-exc-fix/ don't allow exceptions to propagate by default
Patrick Strawderman
patrick at zope.com
Mon Oct 17 16:38:00 EST 2011
Log message for revision 123100:
don't allow exceptions to propagate by default
Changed:
A bobo/branches/patrick-exc-fix/
U bobo/branches/patrick-exc-fix/bobo/src/bobo.py
U bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/boboserver.test
U bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/more.txt
-=-
Modified: bobo/branches/patrick-exc-fix/bobo/src/bobo.py
===================================================================
--- bobo/trunk/bobo/src/bobo.py 2011-10-17 14:51:36 UTC (rev 123099)
+++ bobo/branches/patrick-exc-fix/bobo/src/bobo.py 2011-10-17 21:37:59 UTC (rev 123100)
@@ -34,10 +34,13 @@
__metaclass__ = type
+import logging
import re
import sys
import webob
+log = logging.getLogger(__name__)
+
bbbbad_errors = KeyboardInterrupt, SystemExit, MemoryError
_default_content_type = 'text/html; charset=UTF-8'
@@ -193,12 +196,12 @@
return self.method_not_allowed(request, method, v.allowed)
except MissingFormVariable, v:
return self.missing_form_variable(request, method, v.name)
- except NotFound, v:
+ except NotFound:
return self.not_found(request, method)
except bbbbad_errors:
raise
except Exception:
- if not hasattr(self, 'exception'):
+ if request.environ.get("x-wsgiorg.throw_errors"):
raise
return self.exception(request, method, sys.exc_info())
@@ -278,6 +281,13 @@
"Method Not Allowed", "Invalid request method: %s" % method,
[('Allow', ', '.join(sorted(methods)))])
+ def exception(self, request, method, exc_info):
+ log.exception(request.url)
+ return _err_response(
+ 500, method,
+ "Internal Server Error", "An error occurred.")
+
+
def _err_response(status, method, title, message, headers=()):
response = webob.Response(status=status, headerlist=headers or [])
response.content_type = 'text/html; charset=UTF-8'
Modified: bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/boboserver.test
===================================================================
--- bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/boboserver.test 2011-10-17 14:51:36 UTC (rev 123099)
+++ bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/boboserver.test 2011-10-17 21:37:59 UTC (rev 123100)
@@ -138,7 +138,7 @@
Serving ['foo', 'bobo__main__'] on port 80...
serve_forever '' 80
- >>> try: req('/x')
+ >>> try: req('/x', environ={"x-wsgiorg.throw_errors": "1"})
... except Exception, v: print 'raised', v
... else: print '???'
... # doctest: +ELLIPSIS
Modified: bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/more.txt
===================================================================
--- bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/more.txt 2011-10-17 14:51:36 UTC (rev 123099)
+++ bobo/branches/patrick-exc-fix/bobodoctestumentation/src/bobodoctestumentation/more.txt 2011-10-17 21:37:59 UTC (rev 123100)
@@ -541,7 +541,7 @@
Error response generation
-------------------------
-There are three cases for which bobo has to generate error responses:
+There are four cases for which bobo has to generate error responses:
1. When a resource can't be found, bobo generates a "404 Not Found"
response.
@@ -551,6 +551,9 @@
parameter and the parameter is isn't in the given form data, bobo
generates a "405 Forbidden" response with a body that indicates the
missing parameter.
+4. When a route handler raises an exception, bobo generates a
+ "500 Internal Server Error" response.
+
For each of these responses, bobo generates a small HTML body.
@@ -745,11 +748,14 @@
Uncaught exceptions
~~~~~~~~~~~~~~~~~~~
-Normally, bobo let's uncaught exceptions propagate to calling
-middleware or servers. If you want to provide custom handling of
-uncaught exceptions, you can include an ``exception`` method in
-the object you give to ``bobo_errors``.
+Normally, bobo does not let uncaught exceptions propagate; however,
+if the `x-wsgiorg.throw_errors` key is present in the environment,
+any uncaught exceptions will be raised.
+If you want to provide custom handling of uncaught exceptions,
+you can include an ``exception`` method in the object you
+give to ``bobo_errors``.
+
::
import bobo, webob
@@ -780,11 +786,32 @@
>>> update_module('badapp',
... 'import bobo\n\n at bobo.resource\ndef bad(x, y):\n pass\n')
>>> app = webtest.TestApp(bobo.Application(bobo_resources='badapp'))
- >>> app.get('/bad.html')
+ >>> print app.get('/bad.html', status=500).body
+ <html>
+ <head><title>Internal Server Error</title></head>
+ <body>An error occurred.</body>
+ </html>
+ <BLANKLINE>
+
+ The default exception handler logs the traceback.
+
+ >>> import logging
+ >>> import sys
+ >>> handler = logging.StreamHandler(sys.stdout)
+ >>> bobo.log.addHandler(handler)
+ >>> app.get('/bad.html', status=500) and None # doctest: +ELLIPSIS
+ http://localhost/bad.html
Traceback (most recent call last):
...
TypeError: bad() takes exactly 2 arguments (1 given)
+
+ >>> bobo.log.removeHandler(handler)
+ >>> app.get("/bad.html", extra_environ={"x-wsgiorg.throw_errors": "1"})
+ Traceback (most recent call last):
+ ...
+ TypeError: bad() takes exactly 2 arguments (1 given)
+
>>> app = webtest.TestApp(bobo.Application(
... bobo_resources='badapp', bobo_errors='errorsample2:Errors()'))
>>> app.get('/bad.html', status=500).body
More information about the checkins
mailing list