浏览代码

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.
Unai Zalakain 11 年之前
父节点
当前提交
ebb0279f4a
共有 4 个文件被更改,包括 15 次插入2 次删除
  1. 4 1
      django/dispatch/dispatcher.py
  2. 3 1
      docs/releases/1.8.txt
  3. 5 0
      docs/topics/signals.txt
  4. 3 0
      tests/dispatch/tests/test_dispatcher.py

+ 4 - 1
django/dispatch/dispatcher.py

@@ -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
docs/releases/1.8.txt

@@ -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
docs/topics/signals.txt

@@ -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
tests/dispatch/tests/test_dispatcher.py

@@ -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)