Python uses stack traces to track down where exceptions originated from. When an exception bubbles up to the top of a durable coroutine call, and it is interpreted as a fatal error, the coroutine exits and passes the exception to the caller. In this process, we lose the traceback information about the location where the exception was raised, which makes it difficult to track down the origin of an error.
For example, this is the stack trace for a leaf function call:
Traceback (most recent call last):
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 162, in run
return self._run(input)
^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 251, in _run
coroutine_yield = coroutine.run()
^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 116, in run
return self.coroutine.send(None)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/experimental/durable/function.py", line 218, in send
return self.coroutine.send(send)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/main.py", line 10, in get
raise ValueError("This is an error")
And this is the stack trace for the awaiting caller:
Traceback (most recent call last):
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 162, in run
return self._run(input)
^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 251, in _run
coroutine_yield = coroutine.run()
^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/scheduler.py", line 120, in run
return self.coroutine.throw(error)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/experimental/durable/function.py", line 221, in throw
return self.coroutine.throw(typ, val, tb)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/main.py", line 15, in publish
r1 = await get.call('this')
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/experimental/durable/function.py", line 285, in throw
return self.generator.throw(typ, val, tb)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/function.py", line 92, in _call_async
return await dispatch.coroutine.call(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/types.py", line 220, in throw
return self.__wrapped.throw(tp, *rest)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/experimental/durable/function.py", line 285, in throw
return self.generator.throw(typ, val, tb)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/achilleroussel/go/src/github.com/stealthrocket/dispatch-sdk-python/src/dispatch/coroutine.py", line 14, in call
return (yield call)
Bonus to go even further into helping users, we could try to figure out how to remove the stack frames within the SDK to keep the information focused on details relevant to the user.
Python uses stack traces to track down where exceptions originated from. When an exception bubbles up to the top of a durable coroutine call, and it is interpreted as a fatal error, the coroutine exits and passes the exception to the caller. In this process, we lose the traceback information about the location where the exception was raised, which makes it difficult to track down the origin of an error.
For example, this is the stack trace for a leaf function call:
And this is the stack trace for the awaiting caller:
Bonus to go even further into helping users, we could try to figure out how to remove the stack frames within the SDK to keep the information focused on details relevant to the user.