Skip to content

Commit

Permalink
Add IPubFailure event handler
Browse files Browse the repository at this point in the history
  • Loading branch information
rbu authored and Michael Howitz committed May 23, 2018
1 parent 1cd9f05 commit 9da14ff
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
18 changes: 18 additions & 0 deletions src/Products/SiteErrorLog/SiteErrorLog.py
Expand Up @@ -26,17 +26,20 @@
# Python 2
from thread import allocate_lock
from zope.event import notify
from zope.component import provideHandler, adapter
from .interfaces import ErrorRaisedEvent

from AccessControl.class_init import InitializeClass
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.unauthorized import Unauthorized
from Acquisition import aq_base
from Acquisition import aq_acquire
from App.Dialogs import MessageDialog
from OFS.SimpleItem import SimpleItem
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zExceptions.ExceptionFormatter import format_exception
from ZPublisher.interfaces import IPubFailure

LOG = logging.getLogger('Zope.SiteErrorLog')

Expand Down Expand Up @@ -329,3 +332,18 @@ def manage_addErrorLog(dispatcher, RESPONSE=None):
RESPONSE.redirect(
dispatcher.DestinationURL() +
'/manage_main?manage_tabs_message=Error+Log+Added.')

@adapter(IPubFailure)
def _handle_wsgi_publisher_failure(event):
published = event.request.get('PUBLISHED')
if not published:
return

try:
error_log = aq_acquire(published, '__error_log__', containment=1)
except AttributeError:
pass
else:
error_log.raising(event.exc_info)

provideHandler(_handle_wsgi_publisher_failure)
36 changes: 20 additions & 16 deletions src/Products/SiteErrorLog/tests/testSiteErrorLog.py
Expand Up @@ -19,6 +19,8 @@
import transaction
from Testing.makerequest import makerequest
from zope.component import adapter, provideHandler
from zope.event import notify
from ZPublisher.pubevents import PubFailure
import Zope2

from Products.SiteErrorLog.interfaces import IErrorRaisedEvent
Expand Down Expand Up @@ -70,13 +72,13 @@ def testSimpleException(self):
dmeth = self.app.doc
dmeth.manage_upload(file="""<dtml-var expr="1/0">""")

# "Faking out" the automatic involvement of the Site Error Log
# by manually calling the method "raising" that gets invoked
# automatically in a normal web request environment.
# Faking the behavior of the WSGIPublisher (object acquisition,
# view calling and failure notification on exception).
try:
dmeth.__call__()
except ZeroDivisionError:
sel_ob.raising(sys.exc_info())
self.app.REQUEST['PUBLISHED'] = dmeth
notify(PubFailure(self.app.REQUEST, sys.exc_info(), False))

# Now look at the SiteErrorLog, it has one more log entry
self.assertEqual(len(sel_ob.getLogEntries()), previous_log_length + 1)
Expand All @@ -94,13 +96,14 @@ def notifyError(evt):
event_logs.append(evt)

provideHandler(notifyError)
# "Faking out" the automatic involvement of the Site Error Log
# by manually calling the method "raising" that gets invoked
# automatically in a normal web request environment.
# Faking the behavior of the WSGIPublisher (object acquisition,
# view calling and failure notification on exception).
try:
dmeth.__call__()
except ZeroDivisionError:
sel_ob.raising(sys.exc_info())
self.app.REQUEST['PUBLISHED'] = dmeth
notify(PubFailure(self.app.REQUEST, sys.exc_info(), False))

self.assertEqual(len(event_logs), 1)
self.assertEqual(event_logs[0]['type'], 'ZeroDivisionError')
self.assertEqual(event_logs[0]['username'], 'Anonymous User')
Expand All @@ -112,8 +115,9 @@ def testForgetException(self):
try:
raise AttributeError("DummyAttribute")
except AttributeError:
info = sys.exc_info()
elog.raising(info)
self.app.REQUEST['PUBLISHED'] = elog
notify(PubFailure(self.app.REQUEST, sys.exc_info(), False))

previous_log_length = len(elog.getLogEntries())

entries = elog.getLogEntries()
Expand Down Expand Up @@ -142,13 +146,13 @@ def testIgnoredException(self):
dmeth = self.app.doc
dmeth.manage_upload(file="""<dtml-var expr="1/0">""")

# "Faking out" the automatic involvement of the Site Error Log
# by manually calling the method "raising" that gets invoked
# automatically in a normal web request environment.
# Faking the behavior of the WSGIPublisher (object acquisition,
# view calling and failure notification on exception).
try:
dmeth.__call__()
except ZeroDivisionError:
sel_ob.raising(sys.exc_info())
self.app.REQUEST['PUBLISHED'] = dmeth
notify(PubFailure(self.app.REQUEST, sys.exc_info(), False))

# Now look at the SiteErrorLog, it must have the same number of
# log entries
Expand All @@ -161,8 +165,8 @@ def testEntryID(self):
try:
raise AttributeError("DummyAttribute")
except AttributeError:
info = sys.exc_info()
elog.raising(info)
self.app.REQUEST['PUBLISHED'] = elog
notify(PubFailure(self.app.REQUEST, sys.exc_info(), False))

entries = elog.getLogEntries()
entry_id = entries[0]['id']
Expand Down

0 comments on commit 9da14ff

Please sign in to comment.