Commit fc2f28d4 authored by Sidnei da Silva's avatar Sidnei da Silva

- Fix #2155: Wrong parameters being passed to logger's error().

parents 10aa5684 43368b57
......@@ -8,6 +8,9 @@ Zope Changes
Bugs Fixed
- Collector #2155: Fix wrong parameter being passed to
logger's error() method, with tests.
- Updated Five to stable 1.5 release.
- Traversal order changes were causing WebDAV requests which used
......
......@@ -16,7 +16,6 @@ __version__='$Revision: 1.12 $'[11:-2]
from Acquisition import aq_base
from logging import getLogger
import sys
# Interface
......@@ -106,7 +105,7 @@ class MultiHook:
cob(container, request)
except TypeError:
LOG.error('%s call %s failed.' % (
`self._hookname`, `cob`), exc_info=sys.exc_info())
`self._hookname`, `cob`), exc_info=True)
def add(self, cob):
self._list.append(cob)
......@@ -151,6 +150,5 @@ class NameCaller:
# Only catch exceptions that are likely to be logic errors.
# We shouldn't catch Redirects, Unauthorizeds, etc. since
# the programmer may want to raise them deliberately.
LOG.error('BeforeTraverse: Error while invoking hook: "%s"' % self.name,
exc_info=sys.exc_info())
exc_info=True)
import sys
import logging
from Acquisition import Implicit
from ZPublisher import BeforeTraverse
from ZPublisher.BaseRequest import BaseRequest
from ZPublisher.HTTPResponse import HTTPResponse
def makeBaseRequest(root):
response = HTTPResponse()
environment = { 'URL': '',
'PARENTS': [root],
'steps': [],
'_hacked_path': 0,
'_test_counter': 0,
'response': response }
return BaseRequest(environment)
class DummyObjectBasic(Implicit):
""" Dummy class with docstring.
"""
pass
class BrokenHook:
def __call__(self, *args):
print self.__class__.__name__, 'called'
raise TypeError, self.__class__.__name__
def testBeforeTraverse(self):
"""
Zope supports a 'before traverse' hook that is used for several
features, including 'Site Access Rules'. It is implemented using a
special API for registering hooks, and the hooks themselves are
called during traversal by ZPublisher.
>>> root = DummyObjectBasic()
>>> request = makeBaseRequest(root)
>>> container = DummyObjectBasic()
>>> root.container = container
>>> obj = DummyObjectBasic()
>>> container.obj = obj
Setup a broken hook as the before traverse hook for the
container. That will create a 'MultiHook' object:
>>> BeforeTraverse.registerBeforeTraverse(container, BrokenHook(),
... 'broken_hook')
>>> container.__before_publishing_traverse__
<ZPublisher.BeforeTraverse.MultiHook instance at ...>
>>> container.__before_traverse__
{(99, 'broken_hook'): <ZPublisher.tests.testBeforeTraverse.BrokenHook ...>}
Setup logging so we can see the actual exception being logged:
>>> logger = logging.getLogger('ZPublisher')
>>> level = logger.level
>>> handlers = logger.handlers[:]
>>> logger.addHandler(logging.StreamHandler(sys.stdout))
>>> logger.setLevel(logging.ERROR)
Now do the actual traversal:
>>> _ = request.traverse('container/obj')
BrokenHook called
'__before_publishing_traverse__' call ... failed.
Traceback (most recent call last):
...
TypeError: BrokenHook
Unregister the borken hook:
>>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_hook')
The list of 'before traverse' hooks is empty:
>>> container.__before_traverse__
{}
But the 'MultiHook' is not removed:
>>> container.__before_publishing_traverse__
<ZPublisher.BeforeTraverse.MultiHook instance at ...>
If you have an object in the same container that you want to call
during traversal you can register a 'NameCaller' as the hook
instead, and it will delegate to the callable by looking it up as
an attribute of the container:
>>> container.broken_callable = BrokenHook()
>>> BeforeTraverse.registerBeforeTraverse(container,
... BeforeTraverse.NameCaller('broken_callable'),
... 'broken_callable')
>>> container.__before_traverse__
{(99, 'broken_callable'): <ZPublisher.BeforeTraverse.NameCaller ...>}
Now do the actual traversal:
>>> _ = request.traverse('container/obj')
BrokenHook called
BeforeTraverse: Error while invoking hook: "broken_callable"
Traceback (most recent call last):
...
TypeError: BrokenHook
Unregister the borken hook:
>>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_callable')
The list of 'before traverse' hooks is empty:
>>> container.__before_traverse__
{}
But the 'MultiHook' is not removed:
>>> container.__before_publishing_traverse__
<ZPublisher.BeforeTraverse.MultiHook instance at ...>
Finally, restore the logger state:
>>> logger.setLevel(level)
>>> logger.handlers = handlers[:]
"""
pass
from zope.testing import doctest
def test_suite():
return doctest.DocTestSuite(optionflags=doctest.ELLIPSIS)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment