[z3-checkins] r20442 - in z3/FiveException: . trunk
faassen at codespeak.net
faassen at codespeak.net
Wed Nov 30 17:14:40 CET 2005
Author: faassen
Date: Wed Nov 30 17:14:39 2005
New Revision: 20442
Added:
z3/FiveException/
z3/FiveException/trunk/
z3/FiveException/trunk/__init__.py
z3/FiveException/trunk/configure.zcml
z3/FiveException/trunk/error.pt
z3/FiveException/trunk/interfaces.py
z3/FiveException/trunk/monkey.py
Log:
Initial import of FiveException. This is a prototype that adds Zope 3
exception support (exception-views) to Five developed at the Silva
sprint in Vienna.
Added: z3/FiveException/trunk/__init__.py
==============================================================================
--- (empty file)
+++ z3/FiveException/trunk/__init__.py Wed Nov 30 17:14:39 2005
@@ -0,0 +1,5 @@
+# this is a package
+
+def initialize(context):
+ from Products.FiveException.monkey import installExceptionHook
+ installExceptionHook()
Added: z3/FiveException/trunk/configure.zcml
==============================================================================
--- (empty file)
+++ z3/FiveException/trunk/configure.zcml Wed Nov 30 17:14:39 2005
@@ -0,0 +1,23 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ xmlns:five="http://namespaces.zope.org/five">
+
+ <five:implements
+ class="zExceptions.Redirect"
+ interface="Products.FiveException.interfaces.IZope2HandledException"
+ />
+
+ <five:implements
+ class="zExceptions.NotFound"
+ interface="Products.FiveException.interfaces.IZope2NotFound"
+ />
+
+ <browser:page
+ name="index.html"
+ for="Products.FiveException.interfaces.IZope2NotFound"
+ template="error.pt"
+ permission="zope2.Public"
+ />
+
+</configure>
Added: z3/FiveException/trunk/error.pt
==============================================================================
--- (empty file)
+++ z3/FiveException/trunk/error.pt Wed Nov 30 17:14:39 2005
@@ -0,0 +1,5 @@
+<html>
+<body>
+All your base are belong to us.
+</body>
+</html>
Added: z3/FiveException/trunk/interfaces.py
==============================================================================
--- (empty file)
+++ z3/FiveException/trunk/interfaces.py Wed Nov 30 17:14:39 2005
@@ -0,0 +1,11 @@
+from zope.interface import Interface
+
+class IZope2HandledException(Interface):
+ """This exception must be handled by zope 2.
+
+ We don't even try to look up an exception view for it.
+ """
+
+class IZope2NotFound(Interface):
+ pass
+
Added: z3/FiveException/trunk/monkey.py
==============================================================================
--- (empty file)
+++ z3/FiveException/trunk/monkey.py Wed Nov 30 17:14:39 2005
@@ -0,0 +1,100 @@
+import sys
+from types import StringType, ListType
+
+import AccessControl.User
+from Acquisition import aq_acquire
+from ZODB.POSException import ConflictError
+from zLOG import LOG, INFO, BLATHER
+import ZPublisher
+from Zope.App.startup import RequestContainer, app
+from zope.component import getView, ComponentLookupError
+
+from Products.FiveException.interfaces import IZope2HandledException
+
+def zpublisher_exception_hook(published, REQUEST, t, v, traceback):
+ try:
+ if isinstance(t, StringType):
+ if t.lower() in ('unauthorized', 'redirect'):
+ raise
+ else:
+ if t is SystemExit:
+ raise
+ if issubclass(t, ConflictError):
+ # First, we need to close the current connection. We'll
+ # do this by releasing the hold on it. There should be
+ # some sane protocol for this, but for now we'll use
+ # brute force:
+ global conflict_errors
+ conflict_errors = conflict_errors + 1
+ method_name = REQUEST.get('PATH_INFO', '')
+ err = ('ZODB conflict error at %s '
+ '(%s conflicts since startup at %s)')
+ LOG(err % (method_name, conflict_errors, startup_time),
+ INFO, '')
+ LOG('Conflict traceback', BLATHER, '', error=sys.exc_info())
+ raise ZPublisher.Retry(t, v, traceback)
+ if t is ZPublisher.Retry: v.reraise()
+
+ try:
+ log = aq_acquire(published, '__error_log__', containment=1)
+ except AttributeError:
+ error_log_url = ''
+ else:
+ error_log_url = log.raising((t, v, traceback))
+
+ if (getattr(REQUEST.get('RESPONSE', None), '_error_format', '')
+ !='text/html'):
+ raise t, v, traceback
+
+ # XXX do we need this? published is not used by us anymore
+ if (published is None or published is app or
+ type(published) is ListType):
+ # At least get the top-level object
+ published=app.__bobo_traverse__(REQUEST).__of__(
+ RequestContainer(REQUEST))
+
+ # XXX do we need this?
+ if REQUEST.get('AUTHENTICATED_USER', None) is None:
+ REQUEST['AUTHENTICATED_USER']=AccessControl.User.nobody
+
+ # XXX look for zope 3 views instead from here
+ # and then raise the rendered string like raise_standardErrorMessage
+ # does
+
+ # if it's a zope 2 handled exception, we want to bail out to
+ # zope 2 handling immediately
+ if IZope2HandledException.providedBy(v):
+ raise t, v, traceback
+
+ try:
+ view = getView(v, 'index.html', REQUEST)
+ except ComponentLookupError:
+ raise t, v, traceback
+ # XXX utter hack here to fool Five into working. Five should
+ # be using aq_inner() and then this hack can be removed.
+ v.aq_inner = v
+ view = view.__of__(published)
+ message = view()
+ raise t, message, traceback
+ finally:
+ traceback=None
+
+
+def installExceptionHook():
+ print "loading our special error hook!"
+
+ # XXX really hairy hack to get the modules dictionary from the
+ # default argument of get_module_info. We need to modify this in order
+ # modify the err_hook (which is zpublisher_exception_hook) after Zope
+ # has already started up
+ from ZPublisher.Publish import get_module_info
+ # we need to call this once to initialize the modules dictionary
+ get_module_info('Zope')
+ modules = get_module_info.func_defaults[0]
+
+ (bobo_before, bobo_after, object, realm, debug_mode, err_hook,
+ validated_hook, transactions_manager)= modules['Zope']
+ modules['Zope'] = (bobo_before, bobo_after, object, realm,
+ debug_mode, zpublisher_exception_hook,
+ validated_hook, transactions_manager)
+
More information about the z3-checkins
mailing list