0.4 Change the contract of 'handle_exception'. As before, if this method exists on a helper, it is called by the publisher when any other helper step raises an exception. However, unlike its contract in 0.3, it *must* either raise an exception *or* return a three-tuple representing the (status, headers, and body_iter) that will be used to send to our WSGI upstream caller. In particular, it is no longer legal to return None from 'handle_exception'. 'handle_exception' is now a required method on helpers. 0.3 Allow helpers to have a 'handle_exception' method. If this method exists on a helper, it is called by the publisher when any other helper step raises an exception. It is called with a single argument, which will be a three-tuple, representing the type, value, and traceback of the exception that occurred (the result of sys.exc_info()). The 'handle_exception' method should either reraise the exception wholesale (e.g. 'raise t, v, tb') or raise a different exception. The return value of 'handle_exception' is ignored. If the helper's 'handle_exception' returns without raising, or the helper has no 'handle_exception' method, the original exception is re-raised by obob. 0.2 The traversal algorithm implemented in ObobPublisher.__call__ used to be::: current = root for name in helper.path_elements(): helper.before_traverse(current, name) current = helper.traverse(current, name) This presumed that the helper knows about all the path elements before traversing. This is sometimes not the case. To account for this, we now assume the helper provides a method named 'next_name' in order to allow the helper to compose path elements both before and during traversal. The resulting traversal algorithm is:: current = root while 1: helper.before_traverse(current) name = helper.next_name() if name is None: break current = helper.traverse(current, name) Note that the helper 'before_traverse' method is no longer passed the name (because we don't know any name yet). The change to the algorithm is primarily to allow hacks like CMFDynamicType's __before_publishing_traverse__, which modifies the traversal request name stack to find "alias" names. This fixes breakages evident when publishing Plone through repoze.zope2. 0.1 Initial release.