Commit 43368b57 authored by Sidnei da Silva's avatar Sidnei da Silva

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

parent 037c5569
...@@ -16,6 +16,9 @@ Zope Changes ...@@ -16,6 +16,9 @@ Zope Changes
- Usage of 'urljoin' in 'webdav.davcmds' could lead to wrongly - Usage of 'urljoin' in 'webdav.davcmds' could lead to wrongly
constructed urls. constructed urls.
- Collector #2155: Fix wrong parameter being passed to
logger's error() method, with tests.
Zope 2.9.4 (2006/07/21) Zope 2.9.4 (2006/07/21)
Bugs fixed Bugs fixed
......
...@@ -13,10 +13,9 @@ ...@@ -13,10 +13,9 @@
__version__='$Revision: 1.12 $'[11:-2] __version__='$Revision: 1.12 $'[11:-2]
"""BeforeTraverse interface and helper classes""" """BeforeTraverse interface and helper classes"""
import logging
import logging
from Acquisition import aq_base from Acquisition import aq_base
import sys
# Interface # Interface
...@@ -105,7 +104,7 @@ class MultiHook: ...@@ -105,7 +104,7 @@ class MultiHook:
cob(container, request) cob(container, request)
except TypeError: except TypeError:
self.logger.error('%s call %s failed.' % ( self.logger.error('%s call %s failed.' % (
`self._hookname`, `cob`), error=sys.exc_info()) `self._hookname`, `cob`), exc_info=True)
def add(self, cob): def add(self, cob):
self._list.append(cob) self._list.append(cob)
...@@ -151,6 +150,5 @@ class NameCaller: ...@@ -151,6 +150,5 @@ class NameCaller:
# Only catch exceptions that are likely to be logic errors. # Only catch exceptions that are likely to be logic errors.
# We shouldn't catch Redirects, Unauthorizeds, etc. since # We shouldn't catch Redirects, Unauthorizeds, etc. since
# the programmer may want to raise them deliberately. # the programmer may want to raise them deliberately.
import sys
self.logger.error('Error while invoking hook: "%s"' self.logger.error('Error while invoking hook: "%s"'
% self.name, error=sys.exc_info()) % self.name, 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('MultiHook')
>>> 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 ...>}
Setup logging so we can see the actual exception being logged:
>>> bt_logger = logging.getLogger('BeforeTraverse')
>>> bt_level = logger.level
>>> bt_handlers = logger.handlers[:]
>>> bt_logger.addHandler(logging.StreamHandler(sys.stdout))
>>> bt_logger.setLevel(logging.ERROR)
Now do the actual traversal:
>>> _ = request.traverse('container/obj')
BrokenHook called
Error while invoking hook: "broken_callable"
Traceback (most recent call last):
...
TypeError: BrokenHook
Unregister the borken hook:
>>> _ = BeforeTraverse.unregisterBeforeTraverse(container, 'broken_callable')
And restore the logger state:
>>> bt_logger.setLevel(bt_level)
>>> bt_logger.handlers = handlers[:]
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