[Checkins] SVN: bobo/trunk/bobo Merged branches/patrick-exc-fix
jim
cvs-admin at zope.org
Sun Apr 29 16:27:36 UTC 2012
Log message for revision 125411:
Merged branches/patrick-exc-fix
- Bobo now catches application exceptions and generares 500 responses
by default.
Changed:
U bobo/trunk/bobo/README.txt
U bobo/trunk/bobo/src/bobo.py
U bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/boboserver.test
U bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/more.txt
-=-
Modified: bobo/trunk/bobo/README.txt
===================================================================
--- bobo/trunk/bobo/README.txt 2012-04-29 16:17:14 UTC (rev 125410)
+++ bobo/trunk/bobo/README.txt 2012-04-29 16:27:33 UTC (rev 125411)
@@ -33,6 +33,9 @@
when a route doesn't handle a request method, but a later-matching
route does.
+- Bobo now catches application exceptions and generares 500 responses
+ by default.
+
0.2.3 2012-03-12
----------------
Modified: bobo/trunk/bobo/src/bobo.py
===================================================================
--- bobo/trunk/bobo/src/bobo.py 2012-04-29 16:17:14 UTC (rev 125410)
+++ bobo/trunk/bobo/src/bobo.py 2012-04-29 16:27:33 UTC (rev 125411)
@@ -34,11 +34,14 @@
__metaclass__ = type
+import logging
import re
import sys
import urllib
import webob
+log = logging.getLogger(__name__)
+
bbbbad_errors = KeyboardInterrupt, SystemExit, MemoryError
_default_content_type = 'text/html; charset=UTF-8'
@@ -204,7 +207,7 @@
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())
@@ -280,6 +283,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/trunk/bobodoctestumentation/src/bobodoctestumentation/boboserver.test
===================================================================
--- bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/boboserver.test 2012-04-29 16:17:14 UTC (rev 125410)
+++ bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/boboserver.test 2012-04-29 16:27:33 UTC (rev 125411)
@@ -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/trunk/bobodoctestumentation/src/bobodoctestumentation/more.txt
===================================================================
--- bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/more.txt 2012-04-29 16:17:14 UTC (rev 125410)
+++ bobo/trunk/bobodoctestumentation/src/bobodoctestumentation/more.txt 2012-04-29 16:27:33 UTC (rev 125411)
@@ -534,7 +534,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.
@@ -544,7 +544,10 @@
parameter and the parameter is isn't in the given form data, bobo
generates a "403 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.
Applications can take over generating error responses by specifying a
@@ -738,11 +741,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
@@ -773,11 +779,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