fix: avoid dropped errors when transport is closed or uninitialized (#995)

Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
This commit is contained in:
Dariusz Jędrzejczyk 2026-06-04 14:11:32 +02:00 • committed by GitHub
commit df75857fb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 109 additions and 47 deletions

View file

@ -464,7 +464,7 @@ public abstract class AbstractMcpAsyncClientTests {
void testInitializeWithRootsListProviders() {
withClient(createMcpTransport(),
builder -> builder.roots(Root.builder("file:///test/path").name("test-root").build()), client -> {
StepVerifier.create(client.initialize().then(client.closeGracefully())).verifyComplete();
StepVerifier.create(client.initialize()).expectNextCount(1).verifyComplete();
});
}
@ -728,8 +728,6 @@ public abstract class AbstractMcpAsyncClientTests {
builder -> builder.loggingConsumer(notification -> Mono.fromRunnable(() -> logReceived.set(true))),
client -> {
StepVerifier.create(client.initialize()).expectNextMatches(Objects::nonNull).verifyComplete();
StepVerifier.create(client.closeGracefully()).verifyComplete();
});
}

View file

@ -8,11 +8,14 @@ import io.modelcontextprotocol.client.transport.customizer.McpAsyncHttpClientReq
import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer;
import io.modelcontextprotocol.common.McpTransportContext;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpTransportSessionClosedException;
import io.modelcontextprotocol.spec.ProtocolVersions;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -139,13 +142,14 @@ class HttpClientStreamableHttpTransportTest {
var testMessage = new McpSchema.JSONRPCRequest(McpSchema.METHOD_INITIALIZE, "test-id", initializeRequest);
StepVerifier.create(transport.sendMessage(testMessage))
.expectErrorMessage("MCP session has been closed")
.expectErrorMessage("Transport has already been closed.")
.verify();
}
@Test
void testCloseInitialized() {
var transport = HttpClientStreamableHttpTransport.builder(host).build();
transport.connect(Function.identity()).block();
var initializeRequest = McpSchema.InitializeRequest
.builder(ProtocolVersions.MCP_2025_11_25, McpSchema.ClientCapabilities.builder().roots(true).build(),
@ -157,7 +161,8 @@ class HttpClientStreamableHttpTransportTest {
StepVerifier.create(transport.closeGracefully()).verifyComplete();
StepVerifier.create(transport.sendMessage(testMessage))
.expectErrorMatches(err -> err.getMessage().matches("MCP session with ID [a-zA-Z0-9-]* has been closed"))
.expectErrorMatches(err -> err instanceof McpTransportSessionClosedException
&& err.getMessage().contains("Transport has already been closed"))
.verify();
}

View file

@ -81,6 +81,7 @@ class ServerTransportSecurityIntegrationTests {
@AfterEach
void tearDown() {
requestCustomizer.reset();
mcpClient.close();
}