@@ -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
145144def _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