Back to index

plone3  3.1.7
monkey.py
Go to the documentation of this file.
00001 # the following code is "stolen" from (or maybe it was inspired by? :))
00002 # FiveException (http://codespeak.net/svn/z3/FiveException)
00003 
00004 from zope.component import queryMultiAdapter
00005 from Zope2.App.startup import zpublisher_exception_hook
00006 from ZPublisher.Publish import Retry
00007 
00008 
00009 def zpublisher_exception_hook_wrapper(published, REQUEST, t, v, traceback):
00010     """ wrapper around the zope2 zpublisher's error hook """
00011     try:
00012         # if we got a retry exception, we just propagate it instead of
00013         # trying to log it (like FiveException does)
00014         if t is Retry:
00015             v.reraise()
00016         # first we try to find a view/adapter for the current exception and
00017         # let the original function try to handle the exception if we can't
00018         # find one...
00019         view = queryMultiAdapter((v, REQUEST), name='index.html', default=None)
00020         if view is None:
00021             zpublisher_exception_hook(published, REQUEST, t, v, traceback)
00022         else:
00023             # otherwise render the view and raise the rendered string like
00024             # raise_standardErrorMessage does...
00025             view = view.__of__(published)
00026             message = view()
00027             if isinstance(message, unicode):
00028                 message = message.encode('utf-8')
00029             raise t, message, traceback
00030     finally:
00031         traceback = None
00032 
00033 
00034 from ZPublisher.Publish import get_module_info
00035 def proxy_get_module_info(*args, **kwargs):
00036     results = list(get_module_info(*args, **kwargs))
00037     if results[5] is zpublisher_exception_hook:
00038         results[5] = zpublisher_exception_hook_wrapper
00039     return tuple(results)
00040 
00041 
00042 def installExceptionHook():
00043     import ZPublisher.Publish
00044     ZPublisher.Publish.get_module_info = proxy_get_module_info
00045 
00046 
00047 def retry(self):
00048     """ re-initialize a response object to be used in a retry attempt """
00049     # this implementation changes the original one so that the response
00050     # instance is reused instead of replaced with a new one (after a Retry
00051     # exception was raised);  this fixes a bug in zopedoctests' http()
00052     # function (Testing/ZopeTestCase/zopedoctest/functional.py:113);
00053     # the doctest code assumes that the HTTPResponse instance passed to
00054     # publish_module() (line 177) is used to handle to complete request, so
00055     # it can be used to get the status, headers etc later on (lines 183-186);
00056     # normally this is okay, but raising a Retry will create a new response
00057     # instance, which will then hold that data (relevant for evaluating the
00058     # doctest) while the original (passed in) instance is still empty...
00059     #
00060     # so to fix this (quickly) retry() now cleans up and returns itself:
00061     self.__init__(stdout=self.stdout, stderr=self.stderr)
00062     return self
00063 
00064 from ZPublisher.HTTPResponse import HTTPResponse
00065 HTTPResponse.retry = retry
00066