docs: document best practice for handling argument errors in MCP tools (#891)
Resolves #356 Clarify the two-tier error model: - Recoverable tool errors: use CallToolResult with isError(true) - Protocol-level errors: throw McpError / let exceptions propagate as JSON-RPC errors Signed-off-by: Daniel Garnier-Moiroux <git@garnier.wf>
This commit is contained in:
parent
22e7bd4b56
commit
cd2c21c1c8
1 changed files with 39 additions and 0 deletions
|
|
@ -795,3 +795,42 @@ Supported logging levels (in order of increasing severity): DEBUG (0), INFO (1),
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.
|
The SDK provides comprehensive error handling through the McpError class, covering protocol compatibility, transport communication, JSON-RPC messaging, tool execution, resource management, prompt handling, timeouts, and connection issues. This unified error handling approach ensures consistent and reliable error management across both synchronous and asynchronous operations.
|
||||||
|
|
||||||
|
### Error Handling in Tool Implementations
|
||||||
|
|
||||||
|
#### Two Tiers of Errors
|
||||||
|
|
||||||
|
MCP distinguishes between two categories of errors in tool execution:
|
||||||
|
|
||||||
|
**1. Tool-Level Errors (Recoverable by the LLM)**
|
||||||
|
|
||||||
|
Use `CallToolResult` with `isError(true)` for validation failures, missing arguments, or domain errors the LLM can act on and retry.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Example: Domain validation failure (e.g., invalid email format)
|
||||||
|
if (!emailAddress.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
|
||||||
|
return CallToolResult.builder()
|
||||||
|
.content(List.of(new McpSchema.TextContent("Invalid argument: 'email' must be a valid email address.")))
|
||||||
|
.isError(true)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The LLM receives this as part of the normal tool response and can self-correct in a subsequent interaction.
|
||||||
|
|
||||||
|
**2. Protocol-Level Errors (Unrecoverable)**
|
||||||
|
|
||||||
|
Uncaught exceptions from a tool handler are mapped to a JSON-RPC error response. Use this only for truly unexpected failures (e.g., infrastructure errors such as DB timeout), not for input validation.
|
||||||
|
|
||||||
|
```java
|
||||||
|
// This propagates as a JSON-RPC error — use sparingly
|
||||||
|
throw new McpError(McpSchema.ErrorCodes.INTERNAL_ERROR, "Unexpected failure");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Decision Guide
|
||||||
|
|
||||||
|
| Situation | Approach |
|
||||||
|
|------------------------------------|---------------------------------------|
|
||||||
|
| Domain validation failure | `CallToolResult` with `isError=true` |
|
||||||
|
| Infrastructure / unexpected error | Throw `McpError` or let it propagate |
|
||||||
|
| Partial success with a warning | `CallToolResult` with warning in text |
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue