fix(McpActionExecutor): handle client call failures gracefully

This commit is contained in:
2026-04-19 17:27:27 +08:00
parent 8c8b0883bb
commit c5aa558319
2 changed files with 46 additions and 1 deletions

View File

@@ -29,7 +29,14 @@ public class McpActionExecutor {
.name(metaAction.getName())
.arguments(metaAction.getParams())
.build();
McpSchema.CallToolResult callToolResult = mcpClient.callTool(callToolRequest);
McpSchema.CallToolResult callToolResult;
try {
callToolResult = mcpClient.callTool(callToolRequest);
} catch (Exception e) {
response.setOk(false);
response.setData("MCP tool call failed: " + e.getMessage());
return response;
}
Boolean error = callToolResult.isError();
response.setOk(error == null || !error);
response.setData(extractResponseData(callToolResult));

View File

@@ -0,0 +1,38 @@
package work.slhaf.partner.core.action.runner.execution;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import work.slhaf.partner.core.action.entity.MetaAction;
import work.slhaf.partner.core.action.runner.mcp.McpClientRegistry;
import java.lang.reflect.Field;
import java.util.Map;
class McpActionExecutorTest {
@Test
void testRunReturnsFailureWhenClientThrows() {
McpClientRegistry clientRegistry = new McpClientRegistry();
clientRegistry.register("broken", buildThrowingMcpClient());
McpActionExecutor executor = new McpActionExecutor(clientRegistry);
MetaAction metaAction = new MetaAction("demo-tool", false, null, MetaAction.Type.MCP, "broken");
metaAction.getParams().putAll(Map.of("value", "demo"));
var response = executor.run(metaAction);
Assertions.assertFalse(response.isOk());
Assertions.assertTrue(response.getData().startsWith("MCP tool call failed:"));
}
private io.modelcontextprotocol.client.McpSyncClient buildThrowingMcpClient() {
try {
Field unsafeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
sun.misc.Unsafe unsafe = (sun.misc.Unsafe) unsafeField.get(null);
return (io.modelcontextprotocol.client.McpSyncClient) unsafe.allocateInstance(io.modelcontextprotocol.client.McpSyncClient.class);
} catch (Exception e) {
throw new IllegalStateException("failed to build throwing mcp client", e);
}
}
}