[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