Skip to content

Custom error messages from Tools #52

@jwflicker

Description

@jwflicker

Whats the proper way to throw errors from a tool using input/output mapping...

Can we add special handling for Exceptions that are instances of McpError, that use its custom message as the TextContent, and forwards the JSONRPCError jsonRpcError to be returned over jsonrpc?

IIRC the java-sdk has special handling for exceptions thrown of type McpError, but our reflection is wrapping this in a RuntimeException holding a InvocationTargetException holding an McpError.

If i rethrow the wrapped McpError instead of return the generic error message, i can get my expected custom error message to appear

@Override
	public CallToolResult apply(McpSyncServerExchange exchange, CallToolRequest request) {
		validateRequest(request);

		try {
			// Build arguments for the method call, passing the full request for
			// CallToolRequest parameter support
			Object[] args = this.buildMethodArguments(exchange, request.arguments(), request);

			// Invoke the method
			Object result = this.callMethod(args);

			// Return the processed result
			return this.processResult(result);
		}
		catch (Exception e) {
			
			// if underlying error wrapped via reflection is McpError, pass that forward up the stack
			// where it will be handled by the java sdk
			if (e instanceof RuntimeException && 
					e.getCause() instanceof InvocationTargetException &&
					e.getCause().getCause() instanceof McpError) {
				
				throw (McpError)e.getCause().getCause();
				
			}
			return this.createErrorResult(e);
		}

So instead of the generic error:

"Error invoking method: Error invoking method: runSQL"

I can get my custom error content thrown in my McpError:

"MCP error -32603: {"title":"One or more errors occurred while parsing the SQL statement.","exceptionMessage":null,"details":[{"code":5,"message":"\"SELECT\" expected instead of this input","position":{"startOffset":0,"endOffset":4,"startLine":1,"endLine":1,"startCharacter":1,"endCharacter":5}},{"code":5,"message":"\"WHERE\" expected instead of this input","position":{"startOffset":24,"endOffset":27,"startLine":1,"endLine":1,"startCharacter":25,"endCharacter":28}}]}"

If you like this approach i can open a PR

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions