mirror of
https://gitea.com/gitea/gitea-mcp.git
synced 2026-08-25 17:47:44 +00:00
fix: return handler errors and panics as tool results (#230)
Fixes https://gitea.com/gitea/gitea-mcp/issues/229 https://gitea.com/gitea/gitea-mcp/pulls/227 left an unexpected handler error and a recovered panic as JSON-RPC errors, which tell the client the request itself failed and kill the session, as in https://gitea.com/gitea/gitea-mcp/issues/229. Both now return tool results. Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/230 Reviewed-by: bircni <bircni@icloud.com> Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
+3
-8
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"gitea.com/gitea/gitea-mcp/pkg/flag"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/log"
|
||||
"gitea.com/gitea/gitea-mcp/pkg/to"
|
||||
|
||||
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
@@ -90,9 +91,7 @@ func (s ServerTool) MCPHandler() mcp.ToolHandler {
|
||||
return func(ctx context.Context, req *mcp.CallToolRequest) (result *mcp.CallToolResult, err error) {
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
panicErr := fmt.Errorf("panic recovered in %s tool handler: %v", s.Tool.Name, recovered)
|
||||
log.Errorf("%s", panicErr)
|
||||
err = internalError(panicErr)
|
||||
result, err = to.ErrorResult(fmt.Errorf("panic recovered in %s tool handler: %v", s.Tool.Name, recovered))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -107,7 +106,7 @@ func (s ServerTool) MCPHandler() mcp.ToolHandler {
|
||||
if errors.As(err, &protocolErr) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, internalError(err) // Expected failures never reach here, handlers use CallToolResult.
|
||||
return to.ErrorResult(err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -129,10 +128,6 @@ func decodeArguments(raw json.RawMessage) (map[string]any, error) {
|
||||
return arguments, nil
|
||||
}
|
||||
|
||||
func internalError(err error) error {
|
||||
return &jsonrpc.Error{Code: jsonrpc.CodeInternalError, Message: err.Error()}
|
||||
}
|
||||
|
||||
// warnUnmatched logs the names present in allowlist but absent from known,
|
||||
// via logUnmatched, so WarnUnmatchedAllowedTools and WarnUnmatchedAllowedScopes
|
||||
// share the same "collect, sort, no-op when empty" logic and can't drift.
|
||||
|
||||
Reference in New Issue
Block a user