durusmail: quixote-users: cgitb patch
Misc feedback
2002-01-28
2002-01-28
2002-01-29
David Ascher (2 parts)
cgitb patch
2002-01-30
2002-01-30
2002-01-30
2002-01-30
2002-01-30
2002-01-30
2002-01-30
cgitb patch
Andrew Kuchling
2002-01-30
OK; is the third time the charm?  And is there any point in keeping
format_internal_error() if it just returns one of its parameters?

--amk

Index: publish.py
===================================================================
RCS file: /projects/cvsroot/mems/quixote/publish.py,v
retrieving revision 1.107
diff -u -r1.107 publish.py
--- publish.py  24 Jan 2002 16:08:53 -0000      1.107
+++ publish.py  30 Jan 2002 23:48:30 -0000
@@ -12,6 +12,10 @@
 from quixote.http_request import HTTPRequest
 from quixote.http_response import HTTPResponse

+try:
+    import cgitb                        # Only available in Python 2.2
+except ImportError:
+    cgitb = None

 def _get_module (name):
     """Get a module object by name."""
@@ -361,17 +365,11 @@
         Format a response after a non-PublishError exception.
         Applications may wish to subclass this method but they should do
         so carefully.  The application could be broken badly when this
-        method is called.  This probably best to keep the formatting
+        method is called.  It's probably best to keep the formatting
         simple.
         """
-        if self.config.display_exceptions:
-            request.response.set_header("Content-Type", "text/plain")
-            return error_message
-        else:
-            request.response.set_header("Content-Type", "text/html")
-            admin = request.environ.get('SERVER_ADMIN',
-                                   "email address unknown")
-            return INTERNAL_ERROR_MESSAGE % admin
+        return error_message
+

     def finish_failed_request (self, request):
         """
@@ -391,6 +389,44 @@
         error_summary = error_summary[0][0:-1] # de-listify and strip newline
         error_file = cStringIO.StringIO()

+        if not self.config.display_exceptions:
+            # DISPLAY_EXCEPTIONS is false, so return the most
+            # secure (and cryptic) page.
+            self._generate_internal_error(error_file, request)
+        elif self.config.display_exceptions == 'html' and cgitb is not None:
+            # Generate a spiffy HTML display using cgitb
+            self._generate_cgitb_error(error_file,
+                                       request, original_response,
+                                       exc_type, exc_value, tb)
+        else:
+            # Generate a plaintext page containing the traceback
+            self._generate_plaintext_error(error_file,
+                                           request, original_response,
+                                           exc_type, exc_value, tb)
+
+        error_msg = error_file.getvalue()
+        self.error_log.write(error_msg)
+        if request.session is not None:
+            request.session.dump(file=self.error_log)
+
+        if self.config.error_email:
+            self.mail_error(error_msg, error_summary)
+
+        request.response.set_status(500)
+        return self.format_internal_error(request, error_msg)
+
+
+    def _generate_internal_error (self, error_file, request):
+        request.response.set_header("Content-Type", "text/html")
+        admin = request.environ.get('SERVER_ADMIN',
+                                    "email address unknown")
+        error_file.write(INTERNAL_ERROR_MESSAGE % admin)
+
+
+    def _generate_plaintext_error (self,
+                                   error_file, request, original_response,
+                                   exc_type, exc_value, tb):
+        request.response.set_header("Content-Type", "text/plain")
         #self.debug("report_error: exception = %s: %s" % (exc_type, exc_value))

         # record the time of the error
@@ -410,16 +446,18 @@
         original_response.write(error_file)
         error_file.write('='*65 + '\n')

-        error_msg = error_file.getvalue()
-        self.error_log.write(error_msg)
-        if request.session is not None:
-            request.session.dump(file=self.error_log)
-
-        if self.config.error_email:
-            self.mail_error(error_msg, error_summary)
+
+    def _generate_cgitb_error (self, error_file, request, original_response,
+                               exc_type, exc_value, tb):
+        request.response.set_header("Content-Type", "text/html")
+        hook = cgitb.Hook(file=error_file)
+        hook(exc_type, exc_value, tb)
+        error_file.write('

Original Request

') + error_file.write(request.dump_html()) + error_file.write('

Original Response

')
+        original_response.write(error_file)
+        error_file.write('
') - request.response.set_status(500) - return self.format_internal_error(request, error_msg) def mail_error (self, msg, error_summary): """Send an email notifying someone of a traceback.""" Index: config.py =================================================================== RCS file: /projects/cvsroot/mems/quixote/config.py,v retrieving revision 1.33 diff -u -r1.33 config.py --- config.py 28 Nov 2001 15:09:38 -0000 1.33 +++ config.py 30 Jan 2002 23:50:43 -0000 @@ -224,8 +224,12 @@ are all valid. Raise ConfigError with 'source' as the second argument if any problems are found. """ - # This is just here for subclasses to override (for now). - pass + # Check value of DISPLAY_EXCEPTIONS + if self.display_exceptions not in (None, 0, 1, 'plain', 'html'): + raise ConfigError("Must be None," + " 'plain', or 'html'", + source, + "DISPLAY_EXCEPTIONS") def read_file (self, filename):
reply