Commit 4ad8ac12 authored by Martin Aspeli's avatar Martin Aspeli

Merge c105589 from 2.12 branch, adding IPubBeforeAbort event

parent 1b105b23
This diff is collapsed.
......@@ -27,7 +27,7 @@ from zope.security.management import newInteraction, endInteraction
from zope.event import notify
from pubevents import PubStart, PubSuccess, PubFailure, \
PubBeforeCommit, PubAfterTraversal
PubBeforeCommit, PubAfterTraversal, PubBeforeAbort
class Retry(Exception):
"""Raise this to retry a request
......@@ -173,8 +173,12 @@ def publish(request, module_name, after_list, debug=0,
)
retry = True
finally:
# Note: 'abort's can fail. Nevertheless, we want end request handling
try:
notify(PubBeforeAbort(request, exc_info, retry))
if transactions_manager:
transactions_manager.abort()
finally:
......@@ -196,6 +200,9 @@ def publish(request, module_name, after_list, debug=0,
else:
# Note: 'abort's can fail. Nevertheless, we want end request handling
try:
notify(PubBeforeAbort(request, exc_info, False))
if transactions_manager:
transactions_manager.abort()
finally:
......
......@@ -41,5 +41,12 @@ class IPubAfterTraversal(IPubEvent):
class IPubBeforeCommit(IPubEvent):
"""notified immediately before the transaction commit (i.e. after the main
request processing is finished.
request processing is finished).
"""
class IPubBeforeAbort(IPubEvent):
"""notified immediately before the transaction abort (i.e. after the main
request processing is finished, and there was an error).
"""
exc_info = Attribute('''The exception info as returned by 'sys.exc_info()'.''')
retry = Attribute('Whether the request will be retried')
......@@ -10,7 +10,7 @@ for detailed time related analysis, inline request monitoring.
from zope.interface import implements
from interfaces import IPubStart, IPubSuccess, IPubFailure, \
IPubAfterTraversal, IPubBeforeCommit
IPubAfterTraversal, IPubBeforeCommit, IPubBeforeAbort
class _Base(object):
"""PubEvent base class."""
......@@ -42,3 +42,10 @@ class PubAfterTraversal(_Base):
class PubBeforeCommit(_Base):
"""notified immediately before the commit."""
implements(IPubBeforeCommit)
class PubBeforeAbort(_Base):
"""notified immediately before an abort."""
implements(IPubBeforeAbort)
def __init__(self, request, exc_info, retry):
self.request, self.exc_info, self.retry = request, exc_info, retry
......@@ -8,7 +8,7 @@ from zope.event import subscribers
from ZPublisher.Publish import publish, Retry
from ZPublisher.BaseRequest import BaseRequest
from ZPublisher.pubevents import PubStart, PubSuccess, PubFailure, \
PubAfterTraversal, PubBeforeCommit
PubAfterTraversal, PubBeforeCommit, PubBeforeAbort
from ZPublisher.interfaces import \
IPubStart, IPubEnd, IPubSuccess, IPubFailure, \
IPubAfterTraversal, IPubBeforeCommit
......@@ -74,40 +74,58 @@ class TestPubEvents(TestCase):
r = self.request; r.action = 'fail_return'
publish(r, PUBMODULE, [None])
events = self.reporter.events
self.assertEqual(len(events), 2)
self.assertEqual(len(events), 3)
self.assert_(isinstance(events[0], PubStart))
self.assertEqual(events[0].request, r)
self.assert_(isinstance(events[1], PubFailure))
self.assert_(isinstance(events[1], PubBeforeAbort))
self.assertEqual(events[1].request, r)
self.assertEqual(events[1].retry, False)
self.assertEqual(len(events[1].exc_info), 3)
self.assert_(isinstance(events[2], PubFailure))
self.assertEqual(events[2].request, r)
self.assertEqual(events[2].retry, False)
self.assertEqual(len(events[2].exc_info), 3)
def testFailureException(self):
r = self.request; r.action = 'fail_exception'
self.assertRaises(Exception, publish, r, PUBMODULE, [None])
events = self.reporter.events
self.assertEqual(len(events), 2)
self.assertEqual(len(events), 3)
self.assert_(isinstance(events[0], PubStart))
self.assertEqual(events[0].request, r)
self.assert_(isinstance(events[1], PubFailure))
self.assert_(isinstance(events[1], PubBeforeAbort))
self.assertEqual(events[1].request, r)
self.assertEqual(events[1].retry, False)
self.assertEqual(len(events[1].exc_info), 3)
self.assert_(isinstance(events[2], PubFailure))
self.assertEqual(events[2].request, r)
self.assertEqual(events[2].retry, False)
self.assertEqual(len(events[2].exc_info), 3)
def testFailureConflict(self):
r = self.request; r.action = 'conflict'
publish(r, PUBMODULE, [None])
events = self.reporter.events
self.assertEqual(len(events), 6)
self.assertEqual(len(events), 7)
self.assert_(isinstance(events[0], PubStart))
self.assertEqual(events[0].request, r)
self.assert_(isinstance(events[1], PubFailure))
self.assert_(isinstance(events[1], PubBeforeAbort))
self.assertEqual(events[1].request, r)
self.assertEqual(events[1].retry, True)
self.assertEqual(len(events[1].exc_info), 3)
self.assert_(isinstance(events[1].exc_info[1], ConflictError))
self.assert_(isinstance(events[2], PubStart))
self.assert_(isinstance(events[5], PubSuccess))
self.assert_(isinstance(events[2], PubFailure))
self.assertEqual(events[2].request, r)
self.assertEqual(events[2].retry, True)
self.assertEqual(len(events[2].exc_info), 3)
self.assert_(isinstance(events[2].exc_info[1], ConflictError))
self.assert_(isinstance(events[3], PubStart))
self.assert_(isinstance(events[4], PubAfterTraversal))
self.assert_(isinstance(events[5], PubBeforeCommit))
self.assert_(isinstance(events[6], PubSuccess))
# Auxiliaries
def _succeed():
......
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