diff options
| author | Ayush Bansal <ayu023ban@gmail.com> | 2020-12-12 12:58:43 +0530 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-12-15 11:00:26 +0100 |
| commit | b960e4ed722a04a9db0d35293f76e253eedf9126 (patch) | |
| tree | 68473d4ede9a12ef8962a3ae08939659228ab8a1 | |
| parent | 965d2d95c630939b53eb60d9c169f5dfc77ee0c6 (diff) | |
Fixed #32261 -- Added error logging to Signal.send_robust().
| -rw-r--r-- | django/dispatch/dispatcher.py | 9 | ||||
| -rw-r--r-- | docs/releases/3.2.txt | 3 | ||||
| -rw-r--r-- | tests/dispatch/tests.py | 29 |
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): |
