Skip to content

Commit fe91a89

Browse files
fix: clear Scope._transaction when the span is unset
The span setter copied a Transaction's name into _transaction but never cleared it, so after a top-level transaction finished (span restored to None) later events on the same scope kept the stale transaction name. The clear only happens on None: a finishing child span restores the transaction itself, so a live transaction's name is preserved. Fixes getsentry#7774.
1 parent 8afefe8 commit fe91a89

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

‎sentry_sdk/scope.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,8 @@ def span(self, span: "Optional[Span]") -> None:
912912
self._transaction = transaction.name
913913
if transaction.source:
914914
self._transaction_info["source"] = transaction.source
915+
elif span is None:
916+
self._transaction = None
915917

916918
@property
917919
def streamed_span(self) -> "Optional[StreamedSpan]":

‎tests/test_scope.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,3 +1110,43 @@ def test_conversation_id_clear():
11101110

11111111
scope.clear()
11121112
assert scope.get_conversation_id() is None
1113+
1114+
1115+
def test_transaction_name_cleared_when_span_unset():
1116+
"""Scope._transaction follows the span lifecycle (GH-7774).
1117+
1118+
Set by a Transaction, preserved while a child span is active, cleared
1119+
when the span is set back to None (top-level transaction exit).
1120+
"""
1121+
from sentry_sdk.tracing import Transaction
1122+
1123+
scope = Scope()
1124+
1125+
transaction = Transaction(name="my-transaction")
1126+
scope.span = transaction
1127+
assert scope._transaction == "my-transaction"
1128+
1129+
child = transaction.start_child(op="child")
1130+
scope.span = child
1131+
assert scope._transaction == "my-transaction"
1132+
1133+
scope.span = None
1134+
assert scope._transaction is None
1135+
1136+
1137+
def test_transaction_name_survives_nested_span_exit():
1138+
"""Exiting a child span restores the transaction on the scope.
1139+
1140+
The transaction name must not be dropped when an inner span finishes
1141+
while the transaction is still live.
1142+
"""
1143+
scope = Scope()
1144+
1145+
with sentry_sdk.start_transaction(name="my-transaction", scope=scope):
1146+
assert scope._transaction == "my-transaction"
1147+
with sentry_sdk.start_span(op="child", scope=scope):
1148+
assert scope._transaction == "my-transaction"
1149+
# span restored to the transaction, not None
1150+
assert scope._transaction == "my-transaction"
1151+
1152+
assert scope._transaction is None

0 commit comments

Comments
 (0)