Commit 176325b3 authored by Tres Seaver's avatar Tres Seaver

Prevent leaked connections when broken 'EndRequestEvent' subscribers raise.

Fixes #16 on the 2.13 branch.
parent 664186db
...@@ -8,6 +8,9 @@ http://docs.zope.org/zope2/ ...@@ -8,6 +8,9 @@ http://docs.zope.org/zope2/
2.13.23 (unreleased) 2.13.23 (unreleased)
-------------------- --------------------
- Issue #16: prevent leaked connections when broken ``EndRequestEvent``
subscribers raise exceptions.
- LP #1387225: Zope 2.13.x w/ zope.browserpage 4.x doesn't start. - LP #1387225: Zope 2.13.x w/ zope.browserpage 4.x doesn't start.
- LP #1387138: Zope 2.13.x w/ zope.pagetemplate 4.x doesn't start. - LP #1387138: Zope 2.13.x w/ zope.pagetemplate 4.x doesn't start.
......
...@@ -215,10 +215,12 @@ class BaseRequest: ...@@ -215,10 +215,12 @@ class BaseRequest:
self._held=None self._held=None
def close(self): def close(self):
notify(EndRequestEvent(None, self)) try:
# subscribers might need the zodb, so `clear` must come afterwards notify(EndRequestEvent(None, self))
# (since `self._held=None` might close the connection, see above) finally:
self.clear() # subscribers might need the zodb, so `clear` must come afterwards
# (since `self._held=None` might close the connection, see above)
self.clear()
def processInputs(self): def processInputs(self):
"""Do any input processing that could raise errors """Do any input processing that could raise errors
......
...@@ -424,6 +424,22 @@ class TestBaseRequest(unittest.TestCase, BaseRequest_factory): ...@@ -424,6 +424,22 @@ class TestBaseRequest(unittest.TestCase, BaseRequest_factory):
r = self._makeOne(root) r = self._makeOne(root)
self.assertRaises(NotFound, r.traverse, 'folder/simpleFrozenSet') self.assertRaises(NotFound, r.traverse, 'folder/simpleFrozenSet')
def test_close_w_broken_subscriber(self):
# See: https://github.com/zopefoundation/Zope/issues/16
from zope.event import subscribers
root, folder = self._makeRootAndFolder()
r = self._makeOne(root)
r.other['foo'] = 'Foo'
BEFORE = subscribers[:]
def _broken(event):
raise ValueError("I'm broken")
subscribers.append(_broken)
try:
self.assertRaises(ValueError, r.close)
finally:
subscribers[:] = BEFORE
self.assertEqual(r.other, {})
def test_hold_after_close(self): def test_hold_after_close(self):
# Request should no longer accept holds after it has been closed # Request should no longer accept holds after it has been closed
root, folder = self._makeRootAndFolder() root, folder = self._makeRootAndFolder()
......
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