[z3-checkins] r33616 - z3/deliverance/branches/packaged/deliverance

ltucker at codespeak.net ltucker at codespeak.net
Mon Oct 23 20:56:28 CEST 2006


Author: ltucker
Date: Mon Oct 23 20:56:26 2006
New Revision: 33616

Modified:
   z3/deliverance/branches/packaged/deliverance/utils.py
   z3/deliverance/branches/packaged/deliverance/wsgifilter.py
Log:
added rudimentary error page and exception handling for certain errors like bad / missing rules or theme

Modified: z3/deliverance/branches/packaged/deliverance/utils.py
==============================================================================
--- z3/deliverance/branches/packaged/deliverance/utils.py	(original)
+++ z3/deliverance/branches/packaged/deliverance/utils.py	Mon Oct 23 20:56:26 2006
@@ -10,12 +10,36 @@
     warnings.warn(
         'Deliverance requires the CVS HEAD version of libxml2')
 
-class RuleSyntaxError(Exception):
+class DeliveranceError(Exception):
+    """
+    General Deliverance Error.
+    """    
+
+class RuleSyntaxError(DeliveranceError):
     """
     Raised when an invalid or unknown rule is encountered by a renderer 
     during rule processing 
     """
 
+DELIVERANCE_ERROR_PAGE = """
+<html>
+<head>
+  <title>Deliverance Error</title>
+</head>
+<body>
+  <H3>Deliverance Error</H3>
+  <p>An error occurred processing the request<BR>
+  <pre>
+    %s
+  </pre>
+  <p>Stack Trace:
+  <pre>
+    %s
+  </pre>
+</body>
+</html>
+"""
+
 
 class RendererBase(object):
     """

Modified: z3/deliverance/branches/packaged/deliverance/wsgifilter.py
==============================================================================
--- z3/deliverance/branches/packaged/deliverance/wsgifilter.py	(original)
+++ z3/deliverance/branches/packaged/deliverance/wsgifilter.py	Mon Oct 23 20:56:26 2006
@@ -16,12 +16,17 @@
 from interpreter import Renderer
 #from xslt import Renderer
 from htmlserialize import tostring
+from utils import DeliveranceError
+from utils import DELIVERANCE_ERROR_PAGE
 import sys 
 import datetime
 import threading
+import traceback
+from StringIO import StringIO
 
 DELIVERANCE_BASE_URL = 'deliverance.base-url'
 
+
 class DeliveranceMiddleware(object):
 
     def __init__(self, app, theme_uri, rule_uri):
@@ -58,10 +63,26 @@
             elif encoding:
                 return text.decode(encoding)
 
+        try:
+            parsedTheme = parseHTML(theme)
+        except Exception, message:
+            newmessage = "Unable to parse theme page (" + self.theme_uri + ")"
+            if message:
+                newmessage += ":" + str(message)
+            raise DeliveranceError(newmessage)
+
+        try:
+            parsedRule = etree.XML(rule)
+        except Exception, message:
+            newmessage = "Unable to parse rules (" + self.rule_uri + ")"
+            if message:
+                newmessage += ":" + str(message)
+            raise DeliveranceError(newmessage)
+
         return Renderer(
-            theme=parseHTML(theme),
+            theme=parsedTheme,
             theme_uri=full_theme_uri,
-            rule=etree.XML(rule), 
+            rule=parsedRule, 
             rule_uri=self.rule_uri,
             reference_resolver=reference_resolver)
 
@@ -70,35 +91,62 @@
         return self._cache_time + self._timeout < datetime.datetime.now()
 
     def rule(self, environ):
-        return self.get_resource(environ,self.rule_uri)
+        try:
+            return self.get_resource(environ,self.rule_uri)
+        except Exception, message:
+            newmessage = "Unable to retrieve rules from " + self.rule_uri 
+            if message:
+                newmessage += ": " + str(message)
+
+            raise DeliveranceError(newmessage)
 
     def theme(self, environ):
-        return self.get_resource(environ,self.theme_uri)
+        try:
+            return self.get_resource(environ,self.theme_uri)
+        except Exception, message:
+            newmessage = "Unable to retrieve theme page from " + self.theme_uri 
+            if message:
+                newmessage += ": " + str(message)
+            raise DeliveranceError(newmessage)
+
 
     def __call__(self, environ, start_response):
-        qs = environ.get('QUERY_STRING', '')
-        environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False)
-        notheme = 'notheme' in qs
-        if notheme:
-            return self.app(environ, start_response)
-        if 'HTTP_ACCEPT_ENCODING' in environ:
-            del environ['HTTP_ACCEPT_ENCODING']
-
-        status, headers, body = intercept_output(
-            environ, self.app,
-            self.should_intercept,
-            start_response)
-
-
-        if status is None:
-            # should_intercept returned False
-            return body
-
-        body = self.filter_body(environ, body)
-        replace_header(headers, 'content-length', str(len(body)))
-        replace_header(headers, 'content-type', 'text/html; charset=utf-8')
-        start_response(status, headers)
-        return [body]
+        try:
+            qs = environ.get('QUERY_STRING', '')
+            environ[DELIVERANCE_BASE_URL] = construct_url(environ, with_path_info=False, with_query_string=False)
+            notheme = 'notheme' in qs
+            if notheme:
+                return self.app(environ, start_response)
+            if 'HTTP_ACCEPT_ENCODING' in environ:
+                del environ['HTTP_ACCEPT_ENCODING']
+
+            status, headers, body = intercept_output(
+                environ, self.app,
+                self.should_intercept,
+                start_response)
+
+
+            if status is None:
+                # should_intercept returned False
+                return body
+
+            body = self.filter_body(environ, body)
+            replace_header(headers, 'content-length', str(len(body)))
+            replace_header(headers, 'content-type', 'text/html; charset=utf-8')
+            start_response(status, headers)
+            return [body]
+        
+        except DeliveranceError, message:            
+            stack = StringIO()
+            traceback.print_exception(sys.exc_info()[0],
+                                      sys.exc_info()[1],
+                                      sys.exc_info()[2],
+                                      file=stack)
+            status = "500 Internal Server Error"
+            headers = [('Content-type','text/html')]
+            start_response(status,headers)
+            errpage = DELIVERANCE_ERROR_PAGE % (message,stack.getvalue())
+            return [ errpage ]
 
     def should_intercept(self, status, headers):
         type = header_value(headers, 'content-type')
@@ -150,7 +198,7 @@
                 loc = ' location=%r' % loc
             else:
                 loc = ''
-            raise Exception(
+            raise DeliveranceError(
                 "Request for internal resource at %s (%r) failed with status code %r%s"
                 % (construct_url(environ), path_info, status,
                    loc))


More information about the z3-checkins mailing list