Skip to content

Commit ef90c73

Browse files
committed
Fix current scope in wsgi integration
1 parent 1fe8679 commit ef90c73

File tree

1 file changed

+42
-27
lines changed

1 file changed

+42
-27
lines changed

sentry_sdk/integrations/wsgi.py

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
nullcontext,
1313
)
1414
from sentry_sdk.sessions import track_session
15-
from sentry_sdk.scope import use_isolation_scope
1615
from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_ROUTE
1716
from sentry_sdk.utils import (
1817
ContextVar,
@@ -98,6 +97,7 @@ def __call__(self, environ, start_response):
9897
_wsgi_middleware_applied.set(True)
9998
try:
10099
with sentry_sdk.isolation_scope() as scope:
100+
current_scope = sentry_sdk.get_current_scope()
101101
with track_session(scope, session_mode="request"):
102102
with capture_internal_exceptions():
103103
scope.clear_breadcrumbs()
@@ -138,7 +138,12 @@ def __call__(self, environ, start_response):
138138
finally:
139139
_wsgi_middleware_applied.set(False)
140140

141-
return _ScopedResponse(scope, response, transaction)
141+
return _ScopedResponse(
142+
response=response,
143+
current_scope=current_scope,
144+
isolation_scope=scope,
145+
transaction=transaction,
146+
)
142147

143148

144149
def _sentry_start_response( # type: ignore
@@ -224,7 +229,7 @@ def _capture_exception():
224229

225230
class _ScopedResponse:
226231
"""
227-
Users a separate scope for each response chunk.
232+
Use separate scopes for each response chunk.
228233
229234
This will make WSGI apps more tolerant against:
230235
- WSGI servers streaming responses from a different thread/from
@@ -233,44 +238,54 @@ class _ScopedResponse:
233238
- WSGI servers streaming responses interleaved from the same thread
234239
"""
235240

236-
__slots__ = ("_response", "_scope", "_transaction")
241+
__slots__ = ("_response", "_current_scope", "_isolation_scope", "_transaction")
237242

238-
def __init__(self, scope, response, transaction):
239-
# type: (sentry_sdk.scope.Scope, Iterator[bytes], Optional[sentry_sdk.tracing.Transaction]) -> None
240-
self._scope = scope
243+
def __init__(
244+
self,
245+
response, # type: Iterator[bytes]
246+
current_scope, # type: sentry_sdk.scope.Scope
247+
isolation_scope, # type: sentry_sdk.scope.Scope
248+
transaction, # type: Optional[sentry_sdk.tracing.Transaction]
249+
):
250+
# type: (...) -> None
241251
self._response = response
252+
self._current_scope = current_scope
253+
self._isolation_scope = isolation_scope
242254
self._transaction = transaction
243255

244256
def __iter__(self):
245257
# type: () -> Iterator[bytes]
246258
iterator = iter(self._response)
247259

248260
while True:
249-
with use_isolation_scope(self._scope):
250-
try:
251-
chunk = next(iterator)
252-
except StopIteration:
253-
break
254-
except BaseException:
255-
reraise(*_capture_exception())
261+
with sentry_sdk.use_isolation_scope(self._isolation_scope):
262+
with sentry_sdk.use_scope(self._current_scope):
263+
try:
264+
chunk = next(iterator)
265+
except StopIteration:
266+
break
267+
except BaseException:
268+
reraise(*_capture_exception())
256269

257270
yield chunk
258271

259272
def close(self):
260273
# type: () -> None
261-
with use_isolation_scope(self._scope):
262-
try:
263-
self._response.close() # type: ignore
264-
# Close the Sentry transaction
265-
# This is done here to make sure the Transaction stays
266-
# open until all streaming responses are done.
267-
# Of course this here works also for non streaming responses.
268-
if self._transaction is not None:
269-
self._transaction.__exit__(None, None, None)
270-
except AttributeError:
271-
pass
272-
except BaseException:
273-
reraise(*_capture_exception())
274+
with sentry_sdk.use_isolation_scope(self._isolation_scope):
275+
with sentry_sdk.use_scope(self._current_scope):
276+
try:
277+
self._response.close() # type: ignore
278+
279+
# Close the Sentry transaction
280+
# This is done here to make sure the Transaction stays
281+
# open until all streaming responses are done.
282+
# Of course this here works also for non streaming responses.
283+
if self._transaction is not None:
284+
self._transaction.__exit__(None, None, None)
285+
except AttributeError:
286+
pass
287+
except BaseException:
288+
reraise(*_capture_exception())
274289

275290

276291
def _make_wsgi_event_processor(environ, use_x_forwarded_for):

0 commit comments

Comments
 (0)