Fixed #16245 -- Included traceback in send_robust()'s response
Exceptions from the (receiver, exception) tuples returned by ``send_robust()`` now have always their traceback attached as their ``__traceback__`` argument.
This commit is contained in:
parent
79e9da3d1e
commit
ebb0279f4a
|
@ -220,7 +220,8 @@ class Signal(object):
|
||||||
|
|
||||||
If any receiver raises an error (specifically any subclass of
|
If any receiver raises an error (specifically any subclass of
|
||||||
Exception), the error instance is returned as the result for that
|
Exception), the error instance is returned as the result for that
|
||||||
receiver.
|
receiver. The traceback is always attached to the error at
|
||||||
|
``__traceback__``.
|
||||||
"""
|
"""
|
||||||
responses = []
|
responses = []
|
||||||
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
|
||||||
|
@ -232,6 +233,8 @@ class Signal(object):
|
||||||
try:
|
try:
|
||||||
response = receiver(signal=self, sender=sender, **named)
|
response = receiver(signal=self, sender=sender, **named)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
if not hasattr(err, '__traceback__'):
|
||||||
|
err.__traceback__ = sys.exc_info()[2]
|
||||||
responses.append((receiver, err))
|
responses.append((receiver, err))
|
||||||
else:
|
else:
|
||||||
responses.append((receiver, response))
|
responses.append((receiver, response))
|
||||||
|
|
|
@ -153,7 +153,9 @@ Models
|
||||||
Signals
|
Signals
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
* ...
|
* Exceptions from the ``(receiver, exception)`` tuples returned by
|
||||||
|
:meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now have
|
||||||
|
their traceback attached as a ``__traceback__`` attribute.
|
||||||
|
|
||||||
Templates
|
Templates
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
|
@ -274,6 +274,11 @@ be notified of a signal in the face of an error.
|
||||||
and ensures all receivers are notified of the signal. If an error occurs, the
|
and ensures all receivers are notified of the signal. If an error occurs, the
|
||||||
error instance is returned in the tuple pair for the receiver that raised the error.
|
error instance is returned in the tuple pair for the receiver that raised the error.
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
The tracebacks are present on the ``__traceback__`` attribute
|
||||||
|
of the errors returned when calling ``send_robust()``.
|
||||||
|
|
||||||
Disconnecting signals
|
Disconnecting signals
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
import weakref
|
import weakref
|
||||||
|
from types import TracebackType
|
||||||
|
|
||||||
from django.dispatch import Signal, receiver
|
from django.dispatch import Signal, receiver
|
||||||
|
|
||||||
|
@ -134,6 +135,8 @@ class DispatcherTests(unittest.TestCase):
|
||||||
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.assertTrue(isinstance(err.__traceback__, TracebackType))
|
||||||
a_signal.disconnect(fails)
|
a_signal.disconnect(fails)
|
||||||
self._testIsClean(a_signal)
|
self._testIsClean(a_signal)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue