Skip to content

Commit 47e3d43

Browse files
committed
Merge branch 'potel-base' into potel-base-run-all-tests
2 parents 27d50cb + 066ade1 commit 47e3d43

File tree

6 files changed

+66
-201
lines changed

6 files changed

+66
-201
lines changed

sentry_sdk/integrations/wsgi.py

Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import sys
2+
from contextlib import nullcontext
23
from functools import partial
34

45
import sentry_sdk
@@ -8,10 +9,11 @@
89
from sentry_sdk.integrations._wsgi_common import (
910
DEFAULT_HTTP_METHODS_TO_CAPTURE,
1011
_filter_headers,
12+
nullcontext,
1113
)
1214
from sentry_sdk.sessions import track_session
15+
from sentry_sdk.scope import use_isolation_scope
1316
from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_ROUTE
14-
from sentry_sdk.tracing_utils import finish_running_transaction
1517
from sentry_sdk.utils import (
1618
ContextVar,
1719
capture_internal_exceptions,
@@ -44,9 +46,6 @@ def __call__(self, status, response_headers, exc_info=None): # type: ignore
4446
pass
4547

4648

47-
MAX_TRANSACTION_DURATION_SECONDS = 5 * 60
48-
49-
5049
_wsgi_middleware_applied = ContextVar("sentry_wsgi_middleware_applied")
5150

5251
DEFAULT_TRANSACTION_NAME = "generic WSGI request"
@@ -113,7 +112,6 @@ def __call__(self, environ, start_response):
113112
scope.set_transaction_name(
114113
DEFAULT_TRANSACTION_NAME, source=TRANSACTION_SOURCE_ROUTE
115114
)
116-
current_scope = sentry_sdk.get_current_scope()
117115

118116
with track_session(scope, session_mode="request"):
119117
with capture_internal_exceptions():
@@ -124,14 +122,11 @@ def __call__(self, environ, start_response):
124122
environ, self.use_x_forwarded_for
125123
)
126124
)
127-
128125
method = environ.get("REQUEST_METHOD", "").upper()
129126
should_trace = method in self.http_methods_to_capture
130-
transaction = None
131-
132127
with sentry_sdk.continue_trace(environ):
133-
if should_trace:
134-
transaction = sentry_sdk.start_span(
128+
with (
129+
sentry_sdk.start_span(
135130
op=OP.HTTP_SERVER,
136131
name=DEFAULT_TRANSACTION_NAME,
137132
source=TRANSACTION_SOURCE_ROUTE,
@@ -140,9 +135,9 @@ def __call__(self, environ, start_response):
140135
environ, self.use_x_forwarded_for
141136
),
142137
)
143-
transaction.__enter__()
144-
current_scope = transaction.scope
145-
138+
if should_trace
139+
else nullcontext()
140+
) as transaction:
146141
try:
147142
response = self.app(
148143
environ,
@@ -153,20 +148,12 @@ def __call__(self, environ, start_response):
153148
),
154149
)
155150
except BaseException:
156-
exc_info = sys.exc_info()
157-
_capture_exception(exc_info)
158-
finish_running_transaction(transaction, exc_info)
159-
reraise(*exc_info)
151+
reraise(*_capture_exception())
160152

161153
finally:
162154
_wsgi_middleware_applied.set(False)
163155

164-
return _ScopedResponse(
165-
response=response,
166-
current_scope=current_scope,
167-
isolation_scope=scope,
168-
transaction=transaction,
169-
)
156+
return _ScopedResponse(scope, response)
170157

171158

172159
def _sentry_start_response( # type: ignore
@@ -228,13 +215,13 @@ def get_client_ip(environ):
228215
return environ.get("REMOTE_ADDR")
229216

230217

231-
def _capture_exception(exc_info=None):
232-
# type: (Optional[ExcInfo]) -> ExcInfo
218+
def _capture_exception():
219+
# type: () -> ExcInfo
233220
"""
234221
Captures the current exception and sends it to Sentry.
235222
Returns the ExcInfo tuple to it can be reraised afterwards.
236223
"""
237-
exc_info = exc_info or sys.exc_info()
224+
exc_info = sys.exc_info()
238225
e = exc_info[1]
239226

240227
# SystemExit(0) is the only uncaught exception that is expected behavior
@@ -252,7 +239,7 @@ def _capture_exception(exc_info=None):
252239

253240
class _ScopedResponse:
254241
"""
255-
Use separate scopes for each response chunk.
242+
Users a separate scope for each response chunk.
256243
257244
This will make WSGI apps more tolerant against:
258245
- WSGI servers streaming responses from a different thread/from
@@ -261,54 +248,37 @@ class _ScopedResponse:
261248
- WSGI servers streaming responses interleaved from the same thread
262249
"""
263250

264-
__slots__ = ("_response", "_current_scope", "_isolation_scope", "_transaction")
251+
__slots__ = ("_response", "_scope")
265252

266-
def __init__(
267-
self,
268-
response, # type: Iterator[bytes]
269-
current_scope, # type: sentry_sdk.scope.Scope
270-
isolation_scope, # type: sentry_sdk.scope.Scope
271-
transaction=None, # type: Optional[Transaction]
272-
):
273-
# type: (...) -> None
253+
def __init__(self, scope, response):
254+
# type: (sentry_sdk.scope.Scope, Iterator[bytes]) -> None
255+
self._scope = scope
274256
self._response = response
275-
self._current_scope = current_scope
276-
self._isolation_scope = isolation_scope
277-
self._transaction = transaction
278257

279258
def __iter__(self):
280259
# type: () -> Iterator[bytes]
281260
iterator = iter(self._response)
282261

283-
try:
284-
while True:
285-
with sentry_sdk.use_isolation_scope(self._isolation_scope):
286-
with sentry_sdk.use_scope(self._current_scope):
287-
try:
288-
chunk = next(iterator)
289-
except StopIteration:
290-
break
291-
except BaseException:
292-
reraise(*_capture_exception())
293-
294-
yield chunk
262+
while True:
263+
with sentry_sdk.use_isolation_scope(self._scope):
264+
try:
265+
chunk = next(iterator)
266+
except StopIteration:
267+
break
268+
except BaseException:
269+
reraise(*_capture_exception())
295270

296-
finally:
297-
with sentry_sdk.use_isolation_scope(self._isolation_scope):
298-
with sentry_sdk.use_scope(self._current_scope):
299-
finish_running_transaction(transaction=self._transaction)
271+
yield chunk
300272

301273
def close(self):
302274
# type: () -> None
303-
with sentry_sdk.use_isolation_scope(self._isolation_scope):
304-
with sentry_sdk.use_scope(self._current_scope):
305-
try:
306-
finish_running_transaction(transaction=self._transaction)
307-
self._response.close() # type: ignore
308-
except AttributeError:
309-
pass
310-
except BaseException:
311-
reraise(*_capture_exception())
275+
with sentry_sdk.use_isolation_scope(self._scope):
276+
try:
277+
self._response.close() # type: ignore
278+
except AttributeError:
279+
pass
280+
except BaseException:
281+
reraise(*_capture_exception())
312282

313283

314284
def _make_wsgi_event_processor(environ, use_x_forwarded_for):

sentry_sdk/tracing_utils.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@
3636

3737
from types import FrameType
3838

39-
from sentry_sdk._types import ExcInfo
40-
from threading import Timer
41-
4239

4340
SENTRY_TRACE_REGEX = re.compile(
4441
"^[ \t]*" # whitespace
@@ -737,12 +734,3 @@ def get_current_span(scope=None):
737734

738735
if TYPE_CHECKING:
739736
from sentry_sdk.tracing import Span
740-
741-
742-
def finish_running_transaction(transaction=None, exc_info=None):
743-
# type: (Optional[sentry_sdk.Transaction], Optional[ExcInfo]) -> None
744-
if transaction is not None and hasattr(transaction, "_ctx_token"):
745-
if exc_info is not None:
746-
transaction.__exit__(*exc_info)
747-
else:
748-
transaction.__exit__(None, None, None)

tests/integrations/django/test_basic.py

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_view_exceptions(sentry_init, client, capture_exceptions, capture_events
5050
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
5151
exceptions = capture_exceptions()
5252
events = capture_events()
53-
unpack_werkzeug_response(client.get(reverse("view_exc")))
53+
client.get(reverse("view_exc"))
5454

5555
(error,) = exceptions
5656
assert isinstance(error, ZeroDivisionError)
@@ -71,9 +71,7 @@ def test_ensures_x_forwarded_header_is_honored_in_sdk_when_enabled_in_django(
7171
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
7272
exceptions = capture_exceptions()
7373
events = capture_events()
74-
unpack_werkzeug_response(
75-
client.get(reverse("view_exc"), headers={"X_FORWARDED_HOST": "example.com"})
76-
)
74+
client.get(reverse("view_exc"), headers={"X_FORWARDED_HOST": "example.com"})
7775

7876
(error,) = exceptions
7977
assert isinstance(error, ZeroDivisionError)
@@ -92,9 +90,7 @@ def test_ensures_x_forwarded_header_is_not_honored_when_unenabled_in_django(
9290
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
9391
exceptions = capture_exceptions()
9492
events = capture_events()
95-
unpack_werkzeug_response(
96-
client.get(reverse("view_exc"), headers={"X_FORWARDED_HOST": "example.com"})
97-
)
93+
client.get(reverse("view_exc"), headers={"X_FORWARDED_HOST": "example.com"})
9894

9995
(error,) = exceptions
10096
assert isinstance(error, ZeroDivisionError)
@@ -106,7 +102,7 @@ def test_ensures_x_forwarded_header_is_not_honored_when_unenabled_in_django(
106102
def test_middleware_exceptions(sentry_init, client, capture_exceptions):
107103
sentry_init(integrations=[DjangoIntegration()], send_default_pii=True)
108104
exceptions = capture_exceptions()
109-
unpack_werkzeug_response(client.get(reverse("middleware_exc")))
105+
client.get(reverse("middleware_exc"))
110106

111107
(error,) = exceptions
112108
assert isinstance(error, ZeroDivisionError)
@@ -160,7 +156,7 @@ def test_has_trace_if_performance_enabled(sentry_init, client, capture_events):
160156
traces_sample_rate=1.0,
161157
)
162158
events = capture_events()
163-
unpack_werkzeug_response(client.head(reverse("view_exc_with_msg")))
159+
client.head(reverse("view_exc_with_msg"))
164160

165161
(msg_event, error_event, transaction_event) = events
166162

@@ -216,10 +212,8 @@ def test_trace_from_headers_if_performance_enabled(sentry_init, client, capture_
216212
trace_id = "582b43a4192642f0b136d5159a501701"
217213
sentry_trace_header = "{}-{}-{}".format(trace_id, "6e8f22c393e68f19", 1)
218214

219-
unpack_werkzeug_response(
220-
client.head(
221-
reverse("view_exc_with_msg"), headers={"sentry-trace": sentry_trace_header}
222-
)
215+
client.head(
216+
reverse("view_exc_with_msg"), headers={"sentry-trace": sentry_trace_header}
223217
)
224218

225219
(msg_event, error_event, transaction_event) = events
@@ -936,7 +930,7 @@ def test_render_spans(sentry_init, client, capture_events, render_span_tree):
936930

937931
for url, expected_line in views_tests:
938932
events = capture_events()
939-
unpack_werkzeug_response(client.get(url))
933+
client.get(url)
940934
transaction = events[0]
941935
assert expected_line in render_span_tree(transaction)
942936

@@ -980,7 +974,7 @@ def test_middleware_spans(sentry_init, client, capture_events, render_span_tree)
980974
)
981975
events = capture_events()
982976

983-
unpack_werkzeug_response(client.get(reverse("message")))
977+
client.get(reverse("message"))
984978

985979
message, transaction = events
986980

@@ -997,7 +991,7 @@ def test_middleware_spans_disabled(sentry_init, client, capture_events):
997991
)
998992
events = capture_events()
999993

1000-
unpack_werkzeug_response(client.get(reverse("message")))
994+
client.get(reverse("message"))
1001995

1002996
message, transaction = events
1003997

@@ -1021,7 +1015,7 @@ def test_signals_spans(sentry_init, client, capture_events, render_span_tree):
10211015
)
10221016
events = capture_events()
10231017

1024-
unpack_werkzeug_response(client.get(reverse("message")))
1018+
client.get(reverse("message"))
10251019

10261020
message, transaction = events
10271021

@@ -1044,7 +1038,7 @@ def test_signals_spans_disabled(sentry_init, client, capture_events):
10441038
)
10451039
events = capture_events()
10461040

1047-
unpack_werkzeug_response(client.get(reverse("message")))
1041+
client.get(reverse("message"))
10481042

10491043
message, transaction = events
10501044

@@ -1074,7 +1068,7 @@ def test_signals_spans_filtering(sentry_init, client, capture_events, render_spa
10741068
)
10751069
events = capture_events()
10761070

1077-
unpack_werkzeug_response(client.get(reverse("send_myapp_custom_signal")))
1071+
client.get(reverse("send_myapp_custom_signal"))
10781072

10791073
(transaction,) = events
10801074

@@ -1202,7 +1196,7 @@ def test_span_origin(sentry_init, client, capture_events):
12021196
)
12031197
events = capture_events()
12041198

1205-
unpack_werkzeug_response(client.get(reverse("view_with_signal")))
1199+
client.get(reverse("view_with_signal"))
12061200

12071201
(transaction,) = events
12081202

@@ -1232,9 +1226,9 @@ def test_transaction_http_method_default(sentry_init, client, capture_events):
12321226
)
12331227
events = capture_events()
12341228

1235-
unpack_werkzeug_response(client.get(reverse("nomessage")))
1236-
unpack_werkzeug_response(client.options(reverse("nomessage")))
1237-
unpack_werkzeug_response(client.head(reverse("nomessage")))
1229+
client.get(reverse("nomessage"))
1230+
client.options(reverse("nomessage"))
1231+
client.head(reverse("nomessage"))
12381232

12391233
(event,) = events
12401234

@@ -1258,9 +1252,9 @@ def test_transaction_http_method_custom(sentry_init, client, capture_events):
12581252
)
12591253
events = capture_events()
12601254

1261-
unpack_werkzeug_response(client.get(reverse("nomessage")))
1262-
unpack_werkzeug_response(client.options(reverse("nomessage")))
1263-
unpack_werkzeug_response(client.head(reverse("nomessage")))
1255+
client.get("/nomessage")
1256+
client.options("/nomessage")
1257+
client.head("/nomessage")
12641258

12651259
assert len(events) == 2
12661260

0 commit comments

Comments
 (0)