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):