Fixed #32261 -- Added error logging to Signal.send_robust().
This commit is contained in:
parent
965d2d95c6
commit
b960e4ed72
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import warnings
|
import warnings
|
||||||
import weakref
|
import weakref
|
||||||
|
@ -5,6 +6,8 @@ import weakref
|
||||||
from django.utils.deprecation import RemovedInDjango40Warning
|
from django.utils.deprecation import RemovedInDjango40Warning
|
||||||
from django.utils.inspect import func_accepts_kwargs
|
from django.utils.inspect import func_accepts_kwargs
|
||||||
|
|
||||||
|
logger = logging.getLogger('django.dispatch')
|
||||||
|
|
||||||
|
|
||||||
def _make_id(target):
|
def _make_id(target):
|
||||||
if hasattr(target, '__func__'):
|
if hasattr(target, '__func__'):
|
||||||
|
@ -208,6 +211,12 @@ class Signal:
|
||||||
try:
|
try:
|
||||||
response = receiver(signal=self, sender=sender, **named)
|
response = receiver(signal=self, sender=sender, **named)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
logger.error(
|
||||||
|
'Error calling %s in Signal.send_robust() (%s)',
|
||||||
|
receiver.__qualname__,
|
||||||
|
err,
|
||||||
|
exc_info=err,
|
||||||
|
)
|
||||||
responses.append((receiver, err))
|
responses.append((receiver, err))
|
||||||
else:
|
else:
|
||||||
responses.append((receiver, response))
|
responses.append((receiver, response))
|
||||||
|
|
|
@ -420,7 +420,8 @@ Serialization
|
||||||
Signals
|
Signals
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
* ...
|
* :meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now logs
|
||||||
|
exceptions.
|
||||||
|
|
||||||
Templates
|
Templates
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
|
@ -165,12 +165,27 @@ class DispatcherTests(SimpleTestCase):
|
||||||
def fails(val, **kwargs):
|
def fails(val, **kwargs):
|
||||||
raise ValueError('this')
|
raise ValueError('this')
|
||||||
a_signal.connect(fails)
|
a_signal.connect(fails)
|
||||||
result = a_signal.send_robust(sender=self, val="test")
|
try:
|
||||||
|
with self.assertLogs('django.dispatch', 'ERROR') as cm:
|
||||||
|
result = a_signal.send_robust(sender=self, val='test')
|
||||||
err = result[0][1]
|
err = result[0][1]
|
||||||
self.assertIsInstance(err, ValueError)
|
self.assertIsInstance(err, ValueError)
|
||||||
self.assertEqual(err.args, ('this',))
|
self.assertEqual(err.args, ('this',))
|
||||||
self.assertTrue(hasattr(err, '__traceback__'))
|
self.assertIs(hasattr(err, '__traceback__'), True)
|
||||||
self.assertIsInstance(err.__traceback__, TracebackType)
|
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)
|
a_signal.disconnect(fails)
|
||||||
self.assertTestIsClean(a_signal)
|
self.assertTestIsClean(a_signal)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue