From f36e4a78f841ba52fcdd44f852dfaf0921d19b15 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 10 Jun 2026 10:57:41 +0200 Subject: [PATCH 1/5] feat(starlite): Set name and source on route span --- sentry_sdk/integrations/starlite.py | 46 +++++++------- tests/integrations/starlite/test_starlite.py | 63 ++++++++++++++++++++ 2 files changed, 84 insertions(+), 25 deletions(-) diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 21009daa63..93f125b653 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -238,9 +238,27 @@ async def handle_wrapper( request_data = await body - def event_processor(event: "Event", _: "Hint") -> "Event": - route_handler = scope.get("route_handler") + route_handler = scope.get("route_handler") + + func = None + if route_handler.name is not None: + name = route_handler.name + elif isinstance(route_handler.fn, Ref): + func = route_handler.fn.value + else: + func = route_handler.fn + if func is not None: + name = transaction_from_function(func) + + source = SOURCE_FOR_STYLE["endpoint"] + if not name: + name = _DEFAULT_TRANSACTION_NAME + source = TransactionSource.ROUTE + + sentry_sdk.get_current_scope().set_transaction_name(name, source) + + def event_processor(event: "Event", _: "Hint") -> "Event": request_info = event.get("request", {}) request_info["content_length"] = len(scope.get("_body", b"")) if should_send_default_pii(): @@ -248,29 +266,7 @@ def event_processor(event: "Event", _: "Hint") -> "Event": if request_data is not None: request_info["data"] = request_data - func = None - if route_handler.name is not None: - tx_name = route_handler.name - elif isinstance(route_handler.fn, Ref): - func = route_handler.fn.value - else: - func = route_handler.fn - if func is not None: - tx_name = transaction_from_function(func) - - tx_info = {"source": SOURCE_FOR_STYLE["endpoint"]} - - if not tx_name: - tx_name = _DEFAULT_TRANSACTION_NAME - tx_info = {"source": TransactionSource.ROUTE} - - event.update( - { - "request": deepcopy(request_info), - "transaction": tx_name, - "transaction_info": tx_info, - } - ) + event["request"] = deepcopy(request_info) return event sentry_scope._name = StarliteIntegration.identifier diff --git a/tests/integrations/starlite/test_starlite.py b/tests/integrations/starlite/test_starlite.py index 0e7e67fe2a..4761f231f6 100644 --- a/tests/integrations/starlite/test_starlite.py +++ b/tests/integrations/starlite/test_starlite.py @@ -112,6 +112,69 @@ def test_catch_exceptions( assert event["exception"]["values"][0]["mechanism"]["type"] == "starlite" +@pytest.mark.parametrize( + "test_url,expected_tx_name", + [ + ( + "/some_url", + "tests.integrations.starlite.test_starlite.starlite_app_factory..homepage_handler", + ), + ( + "/custom_error", + "custom_name", + ), + ( + "/controller/error", + "partial(.MyController.controller_error>)", + ), + ], +) +@pytest.mark.parametrize("span_streaming", [True, False]) +def test_transaction_name_and_source( + sentry_init, + capture_events, + test_url, + expected_tx_name, + capture_items, + span_streaming, +): + sentry_init( + traces_sample_rate=1.0, + integrations=[StarliteIntegration()], + _experiments={ + "trace_lifecycle": "stream" if span_streaming else "static", + }, + ) + starlite_app = starlite_app_factory() + client = TestClient(starlite_app) + + if span_streaming: + items = capture_items("span") + + try: + client.get(test_url) + except Exception: + pass + + sentry_sdk.flush() + spans = [item.payload for item in items if item.type == "span"] + + spans = [span for span in spans if span["name"] == expected_tx_name] + assert len(spans) == 1 + assert spans[0]["attributes"]["sentry.span.source"] == "component" + else: + events = capture_events() + + try: + client.get(test_url) + except Exception: + pass + + (_, transaction) = events + assert transaction["transaction"] == expected_tx_name + assert transaction["transaction_info"] == {"source": "component"} + + @pytest.mark.parametrize("span_streaming", [True, False]) def test_middleware_spans(sentry_init, capture_events, capture_items, span_streaming): sentry_init( From 6f51f9649754c90b43a2117f408359b65c67547e Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 10 Jun 2026 11:01:16 +0200 Subject: [PATCH 2/5] . --- sentry_sdk/integrations/starlite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 93f125b653..31641fd2fa 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -256,7 +256,7 @@ async def handle_wrapper( name = _DEFAULT_TRANSACTION_NAME source = TransactionSource.ROUTE - sentry_sdk.get_current_scope().set_transaction_name(name, source) + sentry_sdk.set_transaction_name(name, source) def event_processor(event: "Event", _: "Hint") -> "Event": request_info = event.get("request", {}) From 676b378f32205601350b2c29532f91bca507a650 Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 10 Jun 2026 11:34:42 +0200 Subject: [PATCH 3/5] test cleanup --- tests/integrations/starlite/test_starlite.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/integrations/starlite/test_starlite.py b/tests/integrations/starlite/test_starlite.py index 4761f231f6..8998eaf3fd 100644 --- a/tests/integrations/starlite/test_starlite.py +++ b/tests/integrations/starlite/test_starlite.py @@ -157,8 +157,7 @@ def test_transaction_name_and_source( pass sentry_sdk.flush() - spans = [item.payload for item in items if item.type == "span"] - + spans = [item.payload for item in items] spans = [span for span in spans if span["name"] == expected_tx_name] assert len(spans) == 1 assert spans[0]["attributes"]["sentry.span.source"] == "component" From 76ac0e8cb33c6ee06269320f95b7d697c0dfcabb Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 10 Jun 2026 12:45:39 +0200 Subject: [PATCH 4/5] add on isolation scope --- sentry_sdk/integrations/starlite.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 31641fd2fa..1c9328a09d 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -257,6 +257,7 @@ async def handle_wrapper( source = TransactionSource.ROUTE sentry_sdk.set_transaction_name(name, source) + sentry_scope.set_transaction_name(name, source) def event_processor(event: "Event", _: "Hint") -> "Event": request_info = event.get("request", {}) From 0aeabad3811b5fb1945d1ba515627f2fd31a244e Mon Sep 17 00:00:00 2001 From: Alexander Alderman Webb Date: Wed, 10 Jun 2026 13:10:17 +0200 Subject: [PATCH 5/5] align with litestar tests --- tests/integrations/starlite/test_starlite.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integrations/starlite/test_starlite.py b/tests/integrations/starlite/test_starlite.py index 8998eaf3fd..3b6dc44131 100644 --- a/tests/integrations/starlite/test_starlite.py +++ b/tests/integrations/starlite/test_starlite.py @@ -158,7 +158,7 @@ def test_transaction_name_and_source( sentry_sdk.flush() spans = [item.payload for item in items] - spans = [span for span in spans if span["name"] == expected_tx_name] + spans = [span for span in spans if expected_tx_name in span["name"]] assert len(spans) == 1 assert spans[0]["attributes"]["sentry.span.source"] == "component" else: @@ -170,7 +170,7 @@ def test_transaction_name_and_source( pass (_, transaction) = events - assert transaction["transaction"] == expected_tx_name + assert expected_tx_name in transaction["transaction"] assert transaction["transaction_info"] == {"source": "component"}