@@ -1019,6 +1019,71 @@ async def mock_generator(*args, **kwargs):
10191019 await client .close ()
10201020
10211021
1022+ @pytest .mark .asyncio
1023+ @pytest .mark .parametrize (
1024+ 'error_cls,handler_attr,client_method,request_params' ,
1025+ [
1026+ pytest .param (
1027+ UnsupportedOperationError ,
1028+ 'on_subscribe_to_task' ,
1029+ 'subscribe' ,
1030+ SubscribeToTaskRequest (id = 'some-id' ),
1031+ id = 'subscribe' ,
1032+ ),
1033+ ],
1034+ )
1035+ async def test_server_rejects_stream_on_validation_error (
1036+ transport_setups , error_cls , handler_attr , client_method , request_params
1037+ ) -> None :
1038+ """Verify that the server returns an error directly and doesn't open a stream on validation error."""
1039+ client = transport_setups .client
1040+ handler = transport_setups .handler
1041+
1042+ async def mock_generator (* args , ** kwargs ):
1043+ raise error_cls ('Validation failed' )
1044+ yield
1045+
1046+ getattr (handler , handler_attr ).side_effect = mock_generator
1047+
1048+ transport = client ._transport
1049+
1050+ if isinstance (transport , (RestTransport , JsonRpcTransport )):
1051+ # Spy on httpx client to check response headers
1052+ original_send = transport .httpx_client .send
1053+ response_headers = {}
1054+
1055+ async def mock_send (* args , ** kwargs ):
1056+ resp = await original_send (* args , ** kwargs )
1057+ response_headers ['Content-Type' ] = resp .headers .get ('Content-Type' )
1058+ return resp
1059+
1060+ transport .httpx_client .send = mock_send
1061+
1062+ try :
1063+ with pytest .raises (error_cls ):
1064+ async for _ in getattr (client , client_method )(
1065+ request = request_params
1066+ ):
1067+ pass
1068+ finally :
1069+ transport .httpx_client .send = original_send
1070+
1071+ # Verify that the response content type was NOT text/event-stream
1072+ assert not response_headers .get ('Content-Type' , '' ).startswith (
1073+ 'text/event-stream'
1074+ )
1075+ else :
1076+ # For gRPC, we just verify it raises the error
1077+ with pytest .raises (error_cls ):
1078+ async for _ in getattr (client , client_method )(
1079+ request = request_params
1080+ ):
1081+ pass
1082+
1083+ getattr (handler , handler_attr ).side_effect = None
1084+ await client .close ()
1085+
1086+
10221087@pytest .mark .asyncio
10231088@pytest .mark .parametrize (
10241089 'request_kwargs, expected_error_code' ,
0 commit comments