[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