From e0ce2f49ff01a7a3012c1fd6f2ad74dcc7d85294 Mon Sep 17 00:00:00 2001 From: duwenxin Date: Mon, 9 Feb 2026 15:07:52 -0500 Subject: [PATCH] update api err parsing --- internal/server/api.go | 25 ++++++++++++++++++------- internal/util/parameters/parameters.go | 6 +++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/internal/server/api.go b/internal/server/api.go index 5f8a50f640..0c77e24e9e 100644 --- a/internal/server/api.go +++ b/internal/server/api.go @@ -233,16 +233,27 @@ func toolInvokeHandler(s *Server, w http.ResponseWriter, r *http.Request) { params, err := parameters.ParseParams(tool.GetParameters(), data, claimsFromAuth) if err != nil { - // If auth error, return 401 or 403 var clientServerErr *util.ClientServerError - if errors.As(err, &clientServerErr) && (clientServerErr.Code == http.StatusUnauthorized || clientServerErr.Code == http.StatusForbidden) { - s.logger.DebugContext(ctx, fmt.Sprintf("error parsing authenticated parameters from ID token: %s", err)) - _ = render.Render(w, r, newErrResponse(err, clientServerErr.Code)) + + // Return 401 Authentication errors + if errors.As(err, &clientServerErr) && clientServerErr.Code == http.StatusUnauthorized { + s.logger.DebugContext(ctx, fmt.Sprintf("auth error: %v", err)) + _ = render.Render(w, r, newErrResponse(err, http.StatusUnauthorized)) return } - err = fmt.Errorf("provided parameters were invalid: %w", err) - s.logger.DebugContext(ctx, err.Error()) - _ = render.Render(w, r, newErrResponse(err, http.StatusBadRequest)) + + var agentErr *util.AgentError + if errors.As(err, &agentErr) { + s.logger.DebugContext(ctx, fmt.Sprintf("agent validation error: %v", err)) + // We return StatusOK 200 because the API request succeeded, + // even if the agent's logic failed. + _ = render.Render(w, r, newErrResponse(err, http.StatusOK)) + return + } + + // Return 500 if it's a specific ClientServerError that isn't a 401, or any other unexpected error + s.logger.ErrorContext(ctx, fmt.Sprintf("internal server error: %v", err)) + _ = render.Render(w, r, newErrResponse(err, http.StatusInternalServerError)) return } s.logger.DebugContext(ctx, fmt.Sprintf("invocation params: %s", params)) diff --git a/internal/util/parameters/parameters.go b/internal/util/parameters/parameters.go index 77bf9c8e7d..3fc9f9b4df 100644 --- a/internal/util/parameters/parameters.go +++ b/internal/util/parameters/parameters.go @@ -148,20 +148,20 @@ func ParseParams(ps Parameters, data map[string]any, claimsMap map[string]map[st v = p.GetDefault() // if the parameter is required and no value given, throw an error if CheckParamRequired(p.GetRequired(), v) { - return nil, fmt.Errorf("parameter %q is required", name) + return nil, util.NewAgentError(fmt.Sprintf("parameter %q is required", name), nil) } } } else { // parse authenticated parameter v, err = parseFromAuthService(paramAuthServices, claimsMap) if err != nil { - return nil, fmt.Errorf("error parsing authenticated parameter %q: %w", name, err) + return nil, util.NewClientServerError("error parsing authenticated parameter", http.StatusUnauthorized, err) } } if v != nil { newV, err = p.Parse(v) if err != nil { - return nil, fmt.Errorf("unable to parse value for %q: %w", name, err) + return nil, util.NewAgentError("unable to parse value for %q)", err) } } params = append(params, ParamValue{Name: name, Value: newV})