Commit ebb0279f authored by Unai Zalakain's avatar Unai Zalakain Committed by Tim Graham
Browse files

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.
parent 79e9da3d
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -220,7 +220,8 @@ class Signal(object):

        If any receiver raises an error (specifically any subclass of
        Exception), the error instance is returned as the result for that
        receiver.
        receiver. The traceback is always attached to the error at
        ``__traceback__``.
        """
        responses = []
        if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
@@ -232,6 +233,8 @@ class Signal(object):
            try:
                response = receiver(signal=self, sender=sender, **named)
            except Exception as err:
                if not hasattr(err, '__traceback__'):
                    err.__traceback__ = sys.exc_info()[2]
                responses.append((receiver, err))
            else:
                responses.append((receiver, response))
+3 −1
Original line number Diff line number Diff line
@@ -153,7 +153,9 @@ Models
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
^^^^^^^^^
+5 −0
Original line number Diff line number Diff line
@@ -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
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
=====================

+3 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ import sys
import time
import unittest
import weakref
from types import TracebackType

from django.dispatch import Signal, receiver

@@ -134,6 +135,8 @@ class DispatcherTests(unittest.TestCase):
        err = result[0][1]
        self.assertIsInstance(err, ValueError)
        self.assertEqual(err.args, ('this',))
        self.assertTrue(hasattr(err, '__traceback__'))
        self.assertTrue(isinstance(err.__traceback__, TracebackType))
        a_signal.disconnect(fails)
        self._testIsClean(a_signal)