From fdb751217c371882122d14488ecff11a63f85817 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 21 Oct 2022 14:55:07 +0200 Subject: [PATCH] The wrapped receive() did not return anything. (#1698) We wrapped the receive() callback of all ASGI middleware to create spans when they where executed. The receive() callback is used to receive message from the server. But we forgot to return the value that the original receive() callback returns. So basically swallowing the return of the server. Refs #1696 --- sentry_sdk/integrations/starlette.py | 8 ++--- .../integrations/starlette/test_starlette.py | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index aaf7fb3dc4..0bcaf2602f 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -106,7 +106,7 @@ async def _sentry_receive(*args, **kwargs): description=receive.__qualname__, ) as span: span.set_tag("starlette.middleware_name", middleware_name) - await receive(*args, **kwargs) + return await receive(*args, **kwargs) receive_patched = receive.__name__ == "_sentry_receive" new_receive = _sentry_receive if not receive_patched else receive @@ -119,15 +119,15 @@ async def _sentry_send(*args, **kwargs): op=OP.MIDDLEWARE_STARLETTE_SEND, description=send.__qualname__ ) as span: span.set_tag("starlette.middleware_name", middleware_name) - await send(*args, **kwargs) + return await send(*args, **kwargs) send_patched = send.__name__ == "_sentry_send" new_send = _sentry_send if not send_patched else send - await old_call(app, scope, new_receive, new_send, **kwargs) + return await old_call(app, scope, new_receive, new_send, **kwargs) else: - await old_call(app, scope, receive, send, **kwargs) + return await old_call(app, scope, receive, send, **kwargs) not_yet_patched = old_call.__name__ not in [ "_create_span_call", diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index 29e5916adb..713505c61d 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -174,6 +174,21 @@ async def do_stuff(message): await self.app(scope, receive, do_stuff) +class SampleReceiveSendMiddleware: + def __init__(self, app): + self.app = app + + async def __call__(self, scope, receive, send): + message = await receive() + assert message + assert message["type"] == "http.request" + + send_output = await send({"type": "something-unimportant"}) + assert send_output is None + + await self.app(scope, receive, send) + + @pytest.mark.asyncio async def test_starlettrequestextractor_content_length(sentry_init): with mock.patch( @@ -644,6 +659,25 @@ def test_middleware_callback_spans(sentry_init, capture_events): idx += 1 +@pytest.mark.asyncio +async def test_middleware_receive_send(sentry_init, capture_events): + sentry_init( + traces_sample_rate=1.0, + integrations=[StarletteIntegration()], + ) + starlette_app = starlette_app_factory( + middleware=[Middleware(SampleReceiveSendMiddleware)] + ) + + client = TestClient(starlette_app, raise_server_exceptions=False) + try: + # NOTE: the assert statements checking + # for correct behaviour are in `SampleReceiveSendMiddleware`! + client.get("/message", auth=("Gabriela", "hello123")) + except Exception: + pass + + def test_last_event_id(sentry_init, capture_events): sentry_init( integrations=[StarletteIntegration()],