On Mon, Mar 26, 2018 at 10:47 AM, Barry Scott <barry.scott@forcepoint.com> wrote:
On Sunday, 18 March 2018 15:23:58 BST Jean-Paul Calderone wrote:
>
> Try this:
>
>     from twisted.internet.defer import setDebugging
>     setDebugging(True)
>
> This gives you creation and callback stacks in the logs.

If you need to track down who put the value into the deferred
you need to patch the defer.py code to log that info.

There are 2 places that a value enters the Deferred.
The first is the callback() call. The other is in

defer.py:653 Deffered._runCallbacks()

653:                        current.result = callback(current.result, *args,
**kw)

No, you don't:

exarkun@baryon:/tmp$ cat deferreddebug.py 
from twisted.internet.defer import fail, setDebugging
setDebugging(True)
def foo():
    return fail(Exception("boo"))
foo()
exarkun@baryon:/tmp$ python deferreddebug.py 
Unhandled error in Deferred:
(debug:  C: Deferred was created:
 C:  File "deferreddebug.py", line 5, in <module>
 C:    foo()
 C:  File "deferreddebug.py", line 4, in foo
 C:    return fail(Exception("boo"))
 C:  File "/home/exarkun/.local/lib/python2.7/site-packages/twisted/internet/defer.py", line 106, in fail
 C:    d = Deferred()
 I: First Invoker was:
 I:  File "deferreddebug.py", line 5, in <module>
 I:    foo()
 I:  File "deferreddebug.py", line 4, in foo
 I:    return fail(Exception("boo"))
 I:  File "/home/exarkun/.local/lib/python2.7/site-packages/twisted/internet/defer.py", line 107, in fail
 I:    d.errback(result)
)
exarkun@baryon:/tmp$ 

Although it is true that you only get this behavior for the "Unhandled error in Deferred" case.  If you explicitly log a Failure from a Deferred, even with Deferred debugging on, you will not get a callstack for the creator or invoker.  You'll just get whatever callstack the Failure has (and the Failure is independent of the Deferred).

Jean-Paul