Kaydet (Commit) ebb0279f authored tarafından Unai Zalakain's avatar Unai Zalakain Kaydeden (comit) Tim Graham

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.
üst 79e9da3d
......@@ -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))
......
......@@ -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
^^^^^^^^^
......
......@@ -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,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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment