@@ -374,6 +374,7 @@ async def test_proxy_error_in_callback(create_streams):
374374 client_streams , server_streams , (client_read_writer , _ ), (_ , server_write_reader ) = create_streams ()
375375
376376 try :
377+
377378 def failing_error_handler (error : Exception ) -> None :
378379 """Error handler that raises an exception."""
379380 raise RuntimeError ("Callback error" )
@@ -408,6 +409,7 @@ async def test_proxy_async_error_in_callback(create_streams):
408409 client_streams , server_streams , (client_read_writer , _ ), (_ , server_write_reader ) = create_streams ()
409410
410411 try :
412+
411413 async def failing_async_error_handler (error : Exception ) -> None :
412414 """Async error handler that raises an exception."""
413415 await anyio .sleep (0.01 )
@@ -435,3 +437,69 @@ async def failing_async_error_handler(error: Exception) -> None:
435437 # Clean up test streams
436438 await client_read_writer .aclose ()
437439 await server_write_reader .aclose ()
440+
441+
442+ @pytest .mark .anyio
443+ async def test_proxy_without_error_handler (create_streams ):
444+ """Test that proxy works without an error handler (covers onerror=None branch)."""
445+ client_streams , server_streams , (client_read_writer , _ ), (_ , server_write_reader ) = create_streams ()
446+
447+ try :
448+ # Send an exception without an error handler
449+ test_exception = ValueError ("Test error without handler" )
450+
451+ async with mcp_proxy (client_streams , server_streams , onerror = None ):
452+ await client_read_writer .send (test_exception )
453+
454+ # Give it time to process
455+ await anyio .sleep (0.1 )
456+
457+ # Send a valid message - should still work
458+ request = JSONRPCRequest (jsonrpc = "2.0" , id = "after_exception_no_handler" , method = "test" , params = {})
459+ message = SessionMessage (JSONRPCMessage (request ))
460+ await client_read_writer .send (message )
461+
462+ # Valid message should still be forwarded
463+ with anyio .fail_after (1 ):
464+ received = await server_write_reader .receive ()
465+ assert received .message .root .id == "after_exception_no_handler"
466+ finally :
467+ # Clean up test streams
468+ await client_read_writer .aclose ()
469+ await server_write_reader .aclose ()
470+
471+
472+ @pytest .mark .anyio
473+ async def test_proxy_handles_forwarding_exception (create_streams ):
474+ """Test that exceptions during message forwarding are handled."""
475+ client_streams , server_streams , (client_read_writer , _ ), (_ , server_write_reader ) = create_streams ()
476+
477+ try :
478+ errors = []
479+
480+ def error_handler (error : Exception ) -> None :
481+ errors .append (error )
482+
483+ # Create a mock write stream that raises an exception
484+ # We'll close the write stream to simulate an error during send
485+ client_read , client_write = client_streams
486+ server_read , server_write = server_streams
487+
488+ async with mcp_proxy (client_streams , server_streams , onerror = error_handler ):
489+ # Close the write stream to cause an error during forwarding
490+ await server_write .aclose ()
491+
492+ # Send a message - should trigger exception handling
493+ request = JSONRPCRequest (jsonrpc = "2.0" , id = "test" , method = "test" , params = {})
494+ message = SessionMessage (JSONRPCMessage (request ))
495+ await client_read_writer .send (message )
496+
497+ # Give it time to process the error
498+ await anyio .sleep (0.1 )
499+
500+ # Error should have been captured
501+ assert len (errors ) >= 1
502+ finally :
503+ # Clean up test streams
504+ await client_read_writer .aclose ()
505+ await server_write_reader .aclose ()
0 commit comments