summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAyush Bansal <ayu023ban@gmail.com>2020-12-12 12:58:43 +0530
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-12-15 11:00:26 +0100
commitb960e4ed722a04a9db0d35293f76e253eedf9126 (patch)
tree68473d4ede9a12ef8962a3ae08939659228ab8a1
parent965d2d95c630939b53eb60d9c169f5dfc77ee0c6 (diff)
Fixed #32261 -- Added error logging to Signal.send_robust().
-rw-r--r--django/dispatch/dispatcher.py9
-rw-r--r--docs/releases/3.2.txt3
-rw-r--r--tests/dispatch/tests.py29
3 files changed, 33 insertions, 8 deletions
diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py
index b7d9d26389..5ad0659f83 100644
--- a/django/dispatch/dispatcher.py
+++ b/django/dispatch/dispatcher.py
@@ -1,3 +1,4 @@
+import logging
import threading
import warnings
import weakref
@@ -5,6 +6,8 @@ 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__'):
@@ -208,6 +211,12 @@ class Signal:
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))
diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt
index b155f37e00..93b60690b3 100644
--- a/docs/releases/3.2.txt
+++ b/docs/releases/3.2.txt
@@ -420,7 +420,8 @@ Serialization
Signals
~~~~~~~
-* ...
+* :meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now logs
+ exceptions.
Templates
~~~~~~~~~
diff --git a/tests/dispatch/tests.py b/tests/dispatch/tests.py
index 9b5482ed58..30a9354bba 100644
--- a/tests/dispatch/tests.py
+++ b/tests/dispatch/tests.py
@@ -165,13 +165,28 @@ class DispatcherTests(SimpleTestCase):
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):