Ticket #16245: add_traceback_to_send_robust.diff
File add_traceback_to_send_robust.diff, 3.9 KB (added by , 13 years ago) |
---|
-
docs/topics/signals.txt
248 248 pizza_done.send(sender=self, toppings=toppings, size=size) 249 249 ... 250 250 251 Both ``send()`` and ``send_robust()`` return a list of tuple pairs 252 ``[(receiver, response), ... ]``, representing the list of called receiver 253 functions and their response values. 251 ``send()`` returns a list of tuple pairs ``[(receiver, response), ... ]``, 252 representing the list of called receiver functions and their response values. 254 253 255 254 ``send()`` differs from ``send_robust()`` in how exceptions raised by receiver 256 255 functions are handled. ``send()`` does *not* catch any exceptions raised by 257 receivers; it simply allows errors to propagate. Thus not all receivers may 258 benotified of a signal in the face of an error.256 receivers; it simply allows errors to propagate. Thus not all receivers may be 257 notified of a signal in the face of an error. 259 258 260 ``send_robust()`` catches all errors derived from Python's ``Exception`` class, 261 and ensures all receivers are notified of the signal. If an error occurs, the 262 error instance is returned in the tuple pair for the receiver that raised the error. 259 ``send_robust()``, on the other hand, catches all errors derived from Python's 260 ``Exception`` class, and ensures all receivers are notified of the signal. 263 261 262 For receivers that run without raising an exception, ``send_robust()`` appends a 263 tuple pair ``(receiver, response)`` to the returned list, just like ``send()``. If 264 an error occurs, however, a three tuple ``(receiver, error, traceback)`` is appended 265 to the list instead. This tuple contains the receiver that had an error, the 266 ``Exception`` instance raised by that receiver, and a ``traceback`` object with the 267 call stack at the point where the exception occurred. 268 269 .. versionchanged:: 1.4 270 A ``traceback`` object was added to the tuple that is appended to the returned 271 list in ``send_robust()`` when an exception is raised by a receiver function. 272 264 273 Disconnecting signals 265 274 ===================== 266 275 -
django/dispatch/dispatcher.py
1 1 import weakref 2 2 import threading 3 import sys 3 4 4 5 from django.dispatch import saferef 5 6 … … 206 207 try: 207 208 response = receiver(signal=self, sender=sender, **named) 208 209 except Exception, err: 209 responses.append((receiver, err)) 210 # Wrap traceback in try...finally to prevent circular reference 211 # See warning at http://docs.python.org/library/sys.html#sys.exc_info 212 try: 213 traceback = sys.exc_info()[2] 214 responses.append((receiver, err, traceback)) 215 finally: 216 del traceback 210 217 else: 211 218 responses.append((receiver, response)) 212 219 return responses -
tests/regressiontests/dispatch/tests/test_dispatcher.py
1 1 import gc 2 2 import sys 3 from types import TracebackType 3 4 4 5 from django.dispatch import Signal 5 6 from django.utils import unittest … … 98 99 a_signal.connect(fails) 99 100 result = a_signal.send_robust(sender=self, val="test") 100 101 err = result[0][1] 102 traceback = result[0][2] 101 103 self.assertTrue(isinstance(err, ValueError)) 104 self.assertTrue(isinstance(traceback, TracebackType)) 102 105 self.assertEqual(err.args, ('this',)) 103 106 a_signal.disconnect(fails) 104 107 self._testIsClean(a_signal)