Skip to content

Commit 449b2fa

Browse files
authored
fix(scope): Handle token reset LookupErrors gracefully (#4481)
We're surfacing internal SDK errors to users in #4410.
1 parent fedcb07 commit 449b2fa

File tree

2 files changed

+92
-8
lines changed

2 files changed

+92
-8
lines changed

sentry_sdk/scope.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,8 +1673,11 @@ def new_scope():
16731673
yield new_scope
16741674

16751675
finally:
1676-
# restore original scope
1677-
_current_scope.reset(token)
1676+
try:
1677+
# restore original scope
1678+
_current_scope.reset(token)
1679+
except LookupError:
1680+
capture_internal_exception(sys.exc_info())
16781681

16791682

16801683
@contextmanager
@@ -1708,8 +1711,11 @@ def use_scope(scope):
17081711
yield scope
17091712

17101713
finally:
1711-
# restore original scope
1712-
_current_scope.reset(token)
1714+
try:
1715+
# restore original scope
1716+
_current_scope.reset(token)
1717+
except LookupError:
1718+
capture_internal_exception(sys.exc_info())
17131719

17141720

17151721
@contextmanager
@@ -1750,8 +1756,15 @@ def isolation_scope():
17501756

17511757
finally:
17521758
# restore original scopes
1753-
_current_scope.reset(current_token)
1754-
_isolation_scope.reset(isolation_token)
1759+
try:
1760+
_current_scope.reset(current_token)
1761+
except LookupError:
1762+
capture_internal_exception(sys.exc_info())
1763+
1764+
try:
1765+
_isolation_scope.reset(isolation_token)
1766+
except LookupError:
1767+
capture_internal_exception(sys.exc_info())
17551768

17561769

17571770
@contextmanager
@@ -1790,8 +1803,15 @@ def use_isolation_scope(isolation_scope):
17901803

17911804
finally:
17921805
# restore original scopes
1793-
_current_scope.reset(current_token)
1794-
_isolation_scope.reset(isolation_token)
1806+
try:
1807+
_current_scope.reset(current_token)
1808+
except LookupError:
1809+
capture_internal_exception(sys.exc_info())
1810+
1811+
try:
1812+
_isolation_scope.reset(isolation_token)
1813+
except LookupError:
1814+
capture_internal_exception(sys.exc_info())
17951815

17961816

17971817
def should_send_default_pii():

tests/test_scope.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,67 @@ def test_last_event_id_cleared(sentry_init):
905905
Scope.get_isolation_scope().clear()
906906

907907
assert Scope.last_event_id() is None, "last_event_id should be cleared"
908+
909+
910+
@pytest.mark.tests_internal_exceptions
911+
@pytest.mark.parametrize(
912+
"scope_manager",
913+
[
914+
new_scope,
915+
use_scope,
916+
],
917+
)
918+
def test_handle_lookup_error_on_token_reset_current_scope(scope_manager):
919+
with mock.patch("sentry_sdk.scope.capture_internal_exception") as mock_capture:
920+
with mock.patch("sentry_sdk.scope._current_scope") as mock_token_var:
921+
mock_token_var.reset.side_effect = LookupError()
922+
923+
mock_token = mock.Mock()
924+
mock_token_var.set.return_value = mock_token
925+
926+
try:
927+
if scope_manager == use_scope:
928+
with scope_manager(Scope()):
929+
pass
930+
else:
931+
with scope_manager():
932+
pass
933+
934+
except Exception:
935+
pytest.fail("Context manager should handle LookupError gracefully")
936+
937+
mock_capture.assert_called_once()
938+
mock_token_var.reset.assert_called_once_with(mock_token)
939+
940+
941+
@pytest.mark.tests_internal_exceptions
942+
@pytest.mark.parametrize(
943+
"scope_manager",
944+
[
945+
isolation_scope,
946+
use_isolation_scope,
947+
],
948+
)
949+
def test_handle_lookup_error_on_token_reset_isolation_scope(scope_manager):
950+
with mock.patch("sentry_sdk.scope.capture_internal_exception") as mock_capture:
951+
with mock.patch("sentry_sdk.scope._current_scope") as mock_current_scope:
952+
with mock.patch(
953+
"sentry_sdk.scope._isolation_scope"
954+
) as mock_isolation_scope:
955+
mock_isolation_scope.reset.side_effect = LookupError()
956+
mock_current_token = mock.Mock()
957+
mock_current_scope.set.return_value = mock_current_token
958+
959+
try:
960+
if scope_manager == use_isolation_scope:
961+
with scope_manager(Scope()):
962+
pass
963+
else:
964+
with scope_manager():
965+
pass
966+
967+
except Exception:
968+
pytest.fail("Context manager should handle LookupError gracefully")
969+
970+
mock_capture.assert_called_once()
971+
mock_current_scope.reset.assert_called_once_with(mock_current_token)

0 commit comments

Comments
 (0)