Skip to content

Commit 1fe8679

Browse files
committed
Keep transaction open until all streaming responses are finished.
1 parent ec2d929 commit 1fe8679

File tree

1 file changed

+24
-18
lines changed

1 file changed

+24
-18
lines changed

sentry_sdk/integrations/wsgi.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -119,27 +119,26 @@ def __call__(self, environ, start_response):
119119
origin=self.span_origin,
120120
)
121121

122-
with (
123-
sentry_sdk.start_transaction(
122+
if transaction is not None:
123+
transaction = sentry_sdk.start_transaction(
124124
transaction,
125125
custom_sampling_context={"wsgi_environ": environ},
126126
)
127-
if transaction is not None
128-
else nullcontext()
129-
):
130-
try:
131-
response = self.app(
132-
environ,
133-
partial(
134-
_sentry_start_response, start_response, transaction
135-
),
136-
)
137-
except BaseException:
138-
reraise(*_capture_exception())
127+
transaction.__enter__()
128+
129+
try:
130+
response = self.app(
131+
environ,
132+
partial(
133+
_sentry_start_response, start_response, transaction
134+
),
135+
)
136+
except BaseException:
137+
reraise(*_capture_exception())
139138
finally:
140139
_wsgi_middleware_applied.set(False)
141140

142-
return _ScopedResponse(scope, response)
141+
return _ScopedResponse(scope, response, transaction)
143142

144143

145144
def _sentry_start_response( # type: ignore
@@ -234,12 +233,13 @@ class _ScopedResponse:
234233
- WSGI servers streaming responses interleaved from the same thread
235234
"""
236235

237-
__slots__ = ("_response", "_scope")
236+
__slots__ = ("_response", "_scope", "_transaction")
238237

239-
def __init__(self, scope, response):
240-
# type: (sentry_sdk.scope.Scope, Iterator[bytes]) -> None
238+
def __init__(self, scope, response, transaction):
239+
# type: (sentry_sdk.scope.Scope, Iterator[bytes], Optional[sentry_sdk.tracing.Transaction]) -> None
241240
self._scope = scope
242241
self._response = response
242+
self._transaction = transaction
243243

244244
def __iter__(self):
245245
# type: () -> Iterator[bytes]
@@ -261,6 +261,12 @@ def close(self):
261261
with use_isolation_scope(self._scope):
262262
try:
263263
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)
264270
except AttributeError:
265271
pass
266272
except BaseException:

0 commit comments

Comments
 (0)