Description
When capturing errors, the Sentry stack traces only contain the frames from when an error happens. It does not contain any frames from the beginning of the execution.
This screenshot shows that only lines 25 and 17 are tracked (see [1] for full code; link to event). Lines 11 and 29 are missing:
You can also notice that all breadcrumbs are missing [2].
You can check how I hacked a script [3] to give those extra missing frames by using traceback.extract_stack()
; if you're curious.
link to event
[1]
import os
import traceback
import sentry_sdk
from sentry_sdk import capture_exception
sentry_sdk.init(dsn=os.environ.get("SENTRY_DSN"))
def main():
foo() # line 11
def foo():
try:
print("Message before exception")
bar() # line 17
except Exception:
print("Message after capturing exception")
traceback.print_exc()
capture_exception()
def bar():
raise Exception("This is a test exception") # line 25
if __name__ == "__main__":
main() # line 29
[2] Output
Message before exception
Message after capturing exception
Traceback (most recent call last):
File "/Users/armenzg/code/learning/scripts/foo.py", line 16, in foo
bar()
File "/Users/armenzg/code/learning/scripts/foo.py", line 23, in bar
raise Exception("This is a test exception")
Exception: This is a test exception
[3]
import os
import sys
import traceback
import sentry_sdk
from sentry_sdk import capture_exception
# For Python 3.11+
if sys.version_info >= (3, 11):
from builtins import ExceptionGroup
else:
# For Python versions before 3.11
from exceptiongroup import ExceptionGroup
sentry_sdk.init(dsn=os.environ.get("SENTRY_DSN"))
class CustomException(Exception):
def __init__(self, message, tb_frames):
super().__init__(message)
self.tb_frames = tb_frames
def __str__(self):
frames = []
for f in self.tb_frames[:-1]:
# File "sentry_capture_exception.py", line 34, in foo
line1 = f' File "{f[0]}", line {f[1]}, in {f[2]}'
line2 = f" {f[3]}"
frames.append("\n".join([line1, line2]))
tb_str = "\n".join(frames)
# Sample:
# Exception: This is a test exception
# File "sentry_capture_exception.py", line 40, in foo
# bar()
# File "sentry_capture_exception.py", line 58, in bar
# raise Exception("This is a test exception")
return f"{self.__class__.__name__}: foo\n{tb_str}"
def main():
foo()
def foo():
try:
bar()
except Exception as original_error:
stack_trace = traceback.extract_stack()
stack_exception = CustomException("An error occurred", stack_trace)
# Create an ExceptionGroup with the original error and traceback exception
exception_group = ExceptionGroup(
"Error occurred in foo()", [original_error, stack_exception]
)
# Capture the ExceptionGroup
capture_exception(exception_group)
def bar():
raise Exception("This is a test exception")
if __name__ == "__main__":
main()