2424original_propagator = get_global_textmap ()
2525
2626
27+ @pytest .fixture (autouse = True )
28+ def mock_otlp_ingest ():
29+ responses .start ()
30+ responses .add (
31+ responses .POST ,
32+ url = "https://bla.ingest.sentry.io/api/12312012/integration/otlp/v1/traces/" ,
33+ status = 200 ,
34+ )
35+
36+ yield
37+
38+ tracer_provider = get_tracer_provider ()
39+ if isinstance (tracer_provider , TracerProvider ):
40+ tracer_provider .force_flush ()
41+
42+ responses .stop ()
43+ responses .reset ()
44+
45+
2746@pytest .fixture (autouse = True )
2847def reset_otlp (uninstall_integration ):
2948 trace ._TRACER_PROVIDER_SET_ONCE = Once ()
@@ -127,14 +146,7 @@ def test_does_not_set_propagator_if_disabled(sentry_init):
127146 assert propagator is original_propagator
128147
129148
130- @responses .activate
131149def test_otel_propagation_context (sentry_init ):
132- responses .add (
133- responses .POST ,
134- url = "https://bla.ingest.sentry.io/api/12312012/integration/otlp/v1/traces/" ,
135- status = 200 ,
136- )
137-
138150 sentry_init (
139151 dsn = "https://[email protected] /12312012" ,
140152 integrations = [OTLPIntegration ()],
@@ -145,9 +157,6 @@ def test_otel_propagation_context(sentry_init):
145157 with tracer .start_as_current_span ("bar" ) as span :
146158 external_propagation_context = get_external_propagation_context ()
147159
148- # Force flush to ensure spans are exported while mock is active
149- get_tracer_provider ().force_flush ()
150-
151160 assert external_propagation_context is not None
152161 (trace_id , span_id ) = external_propagation_context
153162 assert trace_id == format_trace_id (root_span .get_span_context ().trace_id )
@@ -222,3 +231,74 @@ def test_propagator_inject_continue_trace(sentry_init):
222231 assert carrier ["baggage" ] == incoming_headers ["baggage" ]
223232
224233 detach (token )
234+
235+
236+ def test_capture_exceptions_enabled (sentry_init , capture_events ):
237+ sentry_init (
238+ dsn = "https://[email protected] /12312012" ,
239+ integrations = [OTLPIntegration (capture_exceptions = True )],
240+ )
241+
242+ events = capture_events ()
243+
244+ tracer = trace .get_tracer (__name__ )
245+ with tracer .start_as_current_span ("test_span" ) as span :
246+ try :
247+ raise ValueError ("Test exception" )
248+ except ValueError as e :
249+ span .record_exception (e )
250+
251+ (event ,) = events
252+ assert event ["exception" ]["values" ][0 ]["type" ] == "ValueError"
253+ assert event ["exception" ]["values" ][0 ]["value" ] == "Test exception"
254+ assert event ["exception" ]["values" ][0 ]["mechanism" ]["type" ] == "otlp"
255+ assert event ["exception" ]["values" ][0 ]["mechanism" ]["handled" ] is False
256+
257+ trace_context = event ["contexts" ]["trace" ]
258+ assert trace_context ["trace_id" ] == format_trace_id (
259+ span .get_span_context ().trace_id
260+ )
261+ assert trace_context ["span_id" ] == format_span_id (span .get_span_context ().span_id )
262+
263+
264+ def test_capture_exceptions_disabled (sentry_init , capture_events ):
265+ sentry_init (
266+ dsn = "https://[email protected] /12312012" ,
267+ integrations = [OTLPIntegration (capture_exceptions = False )],
268+ )
269+
270+ events = capture_events ()
271+
272+ tracer = trace .get_tracer (__name__ )
273+ with tracer .start_as_current_span ("test_span" ) as span :
274+ try :
275+ raise ValueError ("Test exception" )
276+ except ValueError as e :
277+ span .record_exception (e )
278+
279+ assert len (events ) == 0
280+
281+
282+ def test_capture_exceptions_preserves_otel_behavior (sentry_init , capture_events ):
283+ sentry_init (
284+ dsn = "https://[email protected] /12312012" ,
285+ integrations = [OTLPIntegration (capture_exceptions = True )],
286+ )
287+
288+ events = capture_events ()
289+
290+ tracer = trace .get_tracer (__name__ )
291+ with tracer .start_as_current_span ("test_span" ) as span :
292+ try :
293+ raise ValueError ("Test exception" )
294+ except ValueError as e :
295+ span .record_exception (e , attributes = {"foo" : "bar" })
296+
297+ # Verify the span recorded the exception (OpenTelemetry behavior)
298+ # The span should have events with the exception information
299+ (otel_event ,) = span ._events
300+ assert otel_event .name == "exception"
301+ assert otel_event .attributes ["foo" ] == "bar"
302+
303+ # verify sentry also captured it
304+ assert len (events ) == 1
0 commit comments