11import  asyncio 
22import  base64 
3+ import  functools 
34import  json 
45import  os 
56
@@ -189,6 +190,30 @@ async def __call__(self, scope, receive, send):
189190        await  self .app (scope , receive , send )
190191
191192
193+ class  SamplePartialReceiveSendMiddleware :
194+     def  __init__ (self , app ):
195+         self .app  =  app 
196+ 
197+     async  def  __call__ (self , scope , receive , send ):
198+         message  =  await  receive ()
199+         assert  message 
200+         assert  message ["type" ] ==  "http.request" 
201+ 
202+         send_output  =  await  send ({"type" : "something-unimportant" })
203+         assert  send_output  is  None 
204+ 
205+         async  def  my_receive (* args , ** kwargs ):
206+             pass 
207+ 
208+         async  def  my_send (* args , ** kwargs ):
209+             pass 
210+ 
211+         partial_receive  =  functools .partial (my_receive )
212+         partial_send  =  functools .partial (my_send )
213+ 
214+         await  self .app (scope , partial_receive , partial_send )
215+ 
216+ 
192217@pytest .mark .asyncio  
193218async  def  test_starlettrequestextractor_content_length (sentry_init ):
194219    with  mock .patch (
@@ -659,8 +684,7 @@ def test_middleware_callback_spans(sentry_init, capture_events):
659684        idx  +=  1 
660685
661686
662- @pytest .mark .asyncio  
663- async  def  test_middleware_receive_send (sentry_init , capture_events ):
687+ def  test_middleware_receive_send (sentry_init , capture_events ):
664688    sentry_init (
665689        traces_sample_rate = 1.0 ,
666690        integrations = [StarletteIntegration ()],
@@ -678,6 +702,79 @@ async def test_middleware_receive_send(sentry_init, capture_events):
678702        pass 
679703
680704
705+ def  test_middleware_partial_receive_send (sentry_init , capture_events ):
706+     sentry_init (
707+         traces_sample_rate = 1.0 ,
708+         integrations = [StarletteIntegration ()],
709+     )
710+     starlette_app  =  starlette_app_factory (
711+         middleware = [Middleware (SamplePartialReceiveSendMiddleware )]
712+     )
713+     events  =  capture_events ()
714+ 
715+     client  =  TestClient (starlette_app , raise_server_exceptions = False )
716+     try :
717+         client .get ("/message" , auth = ("Gabriela" , "hello123" ))
718+     except  Exception :
719+         pass 
720+ 
721+     (_ , transaction_event ) =  events 
722+ 
723+     expected  =  [
724+         {
725+             "op" : "middleware.starlette" ,
726+             "description" : "ServerErrorMiddleware" ,
727+             "tags" : {"starlette.middleware_name" : "ServerErrorMiddleware" },
728+         },
729+         {
730+             "op" : "middleware.starlette" ,
731+             "description" : "SamplePartialReceiveSendMiddleware" ,
732+             "tags" : {"starlette.middleware_name" : "SamplePartialReceiveSendMiddleware" },
733+         },
734+         {
735+             "op" : "middleware.starlette.receive" ,
736+             "description" : "_ASGIAdapter.send.<locals>.receive" 
737+             if  STARLETTE_VERSION  <  (0 , 21 )
738+             else  "_TestClientTransport.handle_request.<locals>.receive" ,
739+             "tags" : {"starlette.middleware_name" : "ServerErrorMiddleware" },
740+         },
741+         {
742+             "op" : "middleware.starlette.send" ,
743+             "description" : "ServerErrorMiddleware.__call__.<locals>._send" ,
744+             "tags" : {"starlette.middleware_name" : "SamplePartialReceiveSendMiddleware" },
745+         },
746+         {
747+             "op" : "middleware.starlette.send" ,
748+             "description" : "_ASGIAdapter.send.<locals>.send" 
749+             if  STARLETTE_VERSION  <  (0 , 21 )
750+             else  "_TestClientTransport.handle_request.<locals>.send" ,
751+             "tags" : {"starlette.middleware_name" : "ServerErrorMiddleware" },
752+         },
753+         {
754+             "op" : "middleware.starlette" ,
755+             "description" : "ExceptionMiddleware" ,
756+             "tags" : {"starlette.middleware_name" : "ExceptionMiddleware" },
757+         },
758+         {
759+             "op" : "middleware.starlette.send" ,
760+             "description" : "functools.partial(<function SamplePartialReceiveSendMiddleware.__call__.<locals>.my_send at " ,
761+             "tags" : {"starlette.middleware_name" : "ExceptionMiddleware" },
762+         },
763+         {
764+             "op" : "middleware.starlette.send" ,
765+             "description" : "functools.partial(<function SamplePartialReceiveSendMiddleware.__call__.<locals>.my_send at " ,
766+             "tags" : {"starlette.middleware_name" : "ExceptionMiddleware" },
767+         },
768+     ]
769+ 
770+     idx  =  0 
771+     for  span  in  transaction_event ["spans" ]:
772+         assert  span ["op" ] ==  expected [idx ]["op" ]
773+         assert  span ["description" ].startswith (expected [idx ]["description" ])
774+         assert  span ["tags" ] ==  expected [idx ]["tags" ]
775+         idx  +=  1 
776+ 
777+ 
681778def  test_last_event_id (sentry_init , capture_events ):
682779    sentry_init (
683780        integrations = [StarletteIntegration ()],
0 commit comments