fix: improve error handling in HttpClientSseClientTransport and add test

- Include response body in error messages for better debugging
- Change sendHttpPost return type from HttpResponse<Void> to HttpResponse<String>
- Use BodyHandlers.ofString() instead of discarding response body
- Add testErrorOnBogusMessage test to verify error handling for invalid JSON-RPC messages
- Test validates that malformed messages return 400 status with descriptive error message

Replace #361

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>

Co-authored-by: jkma <jkma@trip.com>
This commit is contained in:
Christian Tzolov 2025-07-13 10:47:33 +02:00 • committed by Christian Tzolov
commit b678de6514
2 changed files with 14 additions and 4 deletions

View file

@ -424,8 +424,8 @@ public class HttpClientSseClientTransport implements McpClientTransport {
.flatMap(body -> sendHttpPost(messageEndpointUri, body).handle((response, sink) -> { .flatMap(body -> sendHttpPost(messageEndpointUri, body).handle((response, sink) -> {
if (response.statusCode() != 200 && response.statusCode() != 201 && response.statusCode() != 202 if (response.statusCode() != 200 && response.statusCode() != 201 && response.statusCode() != 202
&& response.statusCode() != 206) { && response.statusCode() != 206) {
sink.error(new RuntimeException( sink.error(new RuntimeException("Sending message failed with a non-OK HTTP code: "
"Sending message failed with a non-OK HTTP code: " + response.statusCode())); + response.statusCode() + " - " + response.body()));
} }
else { else {
sink.next(response); sink.next(response);
@ -453,7 +453,7 @@ public class HttpClientSseClientTransport implements McpClientTransport {
}); });
} }
private Mono<HttpResponse<Void>> sendHttpPost(final String endpoint, final String body) { private Mono<HttpResponse<String>> sendHttpPost(final String endpoint, final String body) {
final URI requestUri = Utils.resolveUri(baseUri, endpoint); final URI requestUri = Utils.resolveUri(baseUri, endpoint);
final HttpRequest request = this.requestBuilder.copy() final HttpRequest request = this.requestBuilder.copy()
.uri(requestUri) .uri(requestUri)
@ -461,7 +461,7 @@ public class HttpClientSseClientTransport implements McpClientTransport {
.build(); .build();
// TODO: why discard the body? // TODO: why discard the body?
return Mono.fromFuture(httpClient.sendAsync(request, HttpResponse.BodyHandlers.discarding())); return Mono.fromFuture(httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()));
} }
/** /**

View file

@ -105,6 +105,16 @@ class HttpClientSseClientTransportTests {
container.stop(); container.stop();
} }
@Test
void testErrorOnBogusMessage() {
// bogus message
JSONRPCRequest bogusMessage = new JSONRPCRequest(null, null, "test-id", Map.of("key", "value"));
StepVerifier.create(transport.sendMessage(bogusMessage))
.verifyErrorMessage(
"Sending message failed with a non-OK HTTP code: 400 - Invalid message: {\"id\":\"test-id\",\"params\":{\"key\":\"value\"}}");
}
@Test @Test
void testMessageProcessing() { void testMessageProcessing() {
// Create a test message // Create a test message