Skip to content

Commit

Permalink
Fixed #32261 -- Added error logging to Signal.send_robust().
Browse files Browse the repository at this point in the history
  • Loading branch information
ayu023ban authored and felixxm committed Dec 15, 2020
1 parent 965d2d9 commit b960e4e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
9 changes: 9 additions & 0 deletions django/dispatch/dispatcher.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import logging
import threading
import warnings
import weakref

from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.inspect import func_accepts_kwargs

logger = logging.getLogger('django.dispatch')


def _make_id(target):
if hasattr(target, '__func__'):
Expand Down Expand Up @@ -208,6 +211,12 @@ def send_robust(self, sender, **named):
try:
response = receiver(signal=self, sender=sender, **named)
except Exception as err:
logger.error(
'Error calling %s in Signal.send_robust() (%s)',
receiver.__qualname__,
err,
exc_info=err,
)
responses.append((receiver, err))
else:
responses.append((receiver, response))
Expand Down
3 changes: 2 additions & 1 deletion docs/releases/3.2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,8 @@ Serialization
Signals
~~~~~~~

* ...
* :meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now logs
exceptions.

Templates
~~~~~~~~~
Expand Down
29 changes: 22 additions & 7 deletions tests/dispatch/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,28 @@ def test_send_robust_fail(self):
def fails(val, **kwargs):
raise ValueError('this')
a_signal.connect(fails)
result = a_signal.send_robust(sender=self, val="test")
err = result[0][1]
self.assertIsInstance(err, ValueError)
self.assertEqual(err.args, ('this',))
self.assertTrue(hasattr(err, '__traceback__'))
self.assertIsInstance(err.__traceback__, TracebackType)
a_signal.disconnect(fails)
try:
with self.assertLogs('django.dispatch', 'ERROR') as cm:
result = a_signal.send_robust(sender=self, val='test')
err = result[0][1]
self.assertIsInstance(err, ValueError)
self.assertEqual(err.args, ('this',))
self.assertIs(hasattr(err, '__traceback__'), True)
self.assertIsInstance(err.__traceback__, TracebackType)

log_record = cm.records[0]
self.assertEqual(
log_record.getMessage(),
'Error calling '
'DispatcherTests.test_send_robust_fail.<locals>.fails in '
'Signal.send_robust() (this)',
)
self.assertIsNotNone(log_record.exc_info)
_, exc_value, _ = log_record.exc_info
self.assertIsInstance(exc_value, ValueError)
self.assertEqual(str(exc_value), 'this')
finally:
a_signal.disconnect(fails)
self.assertTestIsClean(a_signal)

def test_disconnection(self):
Expand Down

0 comments on commit b960e4e

Please sign in to comment.