Skip to content

Conversation

@duwenxin99
Copy link
Contributor

@duwenxin99 duwenxin99 commented Feb 2, 2026

  • Use a generic util.ProcessGcpError for GCP sources
  • Use a generic util.ProcessGeneralError for all other sources.

@duwenxin99 duwenxin99 requested review from a team as code owners February 2, 2026 23:41
@duwenxin99 duwenxin99 changed the base branch from main to err-api February 2, 2026 23:41
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @duwenxin99, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the error handling strategy across the tools module. By introducing a new, structured ToolboxError interface and associated error types, it enables more precise categorization of errors into agent-specific issues and server-side protocol problems. This change leads to more consistent error propagation, improved mapping to HTTP and JSON-RPC status codes, and a more robust and maintainable error management system throughout the application.

Highlights

  • Structured Error Handling: Introduced a new structured error hierarchy with the ToolboxError interface, AgentError, and ClientServerError types to provide more granular control over error categorization and propagation.
  • Unified Tool Error Returns: All Tool.Invoke methods across the codebase now consistently return util.ToolboxError instead of a generic error, ensuring a standardized error reporting mechanism for tool executions.
  • Improved HTTP Status Mapping: Refactored server-side error handling in api.go and mcp.go to intelligently map ToolboxError categories to appropriate HTTP status codes (e.g., 200 OK for agent errors, 4xx/5xx for server errors) and JSON-RPC error codes.
  • Centralized GCP Error Processing: Added a ProecessGcpError utility function to convert googleapi.Error instances into ClientServerError with relevant HTTP status codes (401, 403), streamlining error handling for Google Cloud Platform interactions.
  • Deprecation of Generic Unauthorized Error: The util.ErrUnauthorized variable has been removed, with all its previous usages replaced by the new ClientServerError type, providing more context and detail for authorization-related failures.
Changelog
  • internal/server/api.go
    • Removed unused strings import.
    • Updated error handling in toolInvokeHandler to use errors.As with util.ClientServerError and util.ToolboxError for more precise error categorization and HTTP status code assignment.
  • internal/server/common_test.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified MockTool.Invoke method signature to return util.ToolboxError.
  • internal/server/mcp.go
    • Removed unused strings import.
    • Refactored error handling for jsonrpc.INVALID_REQUEST to check for util.ClientServerError codes instead of string matching.
  • internal/server/mcp/v20241105/method.go
    • Removed unused strings import.
    • Replaced direct util.ErrUnauthorized returns with util.NewClientServerError.
    • Updated toolsCallHandler error logic to differentiate between CategoryAgent (returning success with IsError: true) and CategoryServer (returning JSON-RPC errors) using the new ToolboxError interface.
  • internal/server/mcp/v20250326/method.go
    • Removed unused strings import.
    • Replaced direct util.ErrUnauthorized returns with util.NewClientServerError.
    • Updated toolsCallHandler error logic to differentiate between CategoryAgent (returning success with IsError: true) and CategoryServer (returning JSON-RPC errors) using the new ToolboxError interface.
  • internal/server/mcp/v20250618/method.go
    • Removed unused strings import.
    • Replaced direct util.ErrUnauthorized returns with util.NewClientServerError.
    • Updated toolsCallHandler error logic to differentiate between CategoryAgent (returning success with IsError: true) and CategoryServer (returning JSON-RPC errors) using the new ToolboxError interface.
  • internal/server/mcp/v20251125/method.go
    • Removed unused strings import.
    • Replaced direct util.ErrUnauthorized returns with util.NewClientServerError.
    • Updated toolsCallHandler error logic to differentiate between CategoryAgent (returning success with IsError: true) and CategoryServer (returning JSON-RPC errors) using the new ToolboxError interface.
  • internal/tools/alloydb/alloydbcreatecluster/alloydbcreatecluster.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbcreateinstance/alloydbcreateinstance.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbcreateuser/alloydbcreateuser.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbgetcluster/alloydbgetcluster.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbgetinstance/alloydbgetinstance.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbgetuser/alloydbgetuser.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydblistclusters/alloydblistclusters.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydblistinstances/alloydblistinstances.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydblistusers/alloydblistusers.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/alloydb/alloydbwaitforoperation/alloydbwaitforoperation.go
    • Added import for github.com/googleapis/genai-toolbox/internal/util.
    • Modified Invoke method signature to return util.ToolboxError.
    • Replaced fmt.Errorf for parameter validation and timeout errors with util.NewAgentError.
    • Wrapped GCP API errors with util.ProecessGcpError.
  • internal/tools/bigquery/bigqueryconversationalanalytics/bigqueryconversationalanalytics.go
    • Updated authorization error handling to use util.NewClientServerError instead of wrapping util.ErrUnauthorized.
  • internal/tools/tools.go
    • Added import for net/http.
    • Modified the Tool interface's Invoke method signature to return util.ToolboxError.
    • Updated AccessToken.ParseBearerToken to return util.NewClientServerError for invalid bearer tokens.
  • internal/util/errors.go
    • New file added, defining the ToolboxError interface, AgentError struct (for agent-specific errors), ClientServerError struct (for server/client protocol errors), and ProecessGcpError function.
  • internal/util/parameters/parameters.go
    • Added import for net/http.
    • Updated parseFromAuthService to return util.NewClientServerError for missing or invalid authentication headers.
  • internal/util/util.go
    • Removed the deprecated ErrUnauthorized variable.
    • Removed unused errors import.
Activity
  • The author duwenxin99 has undertaken a significant refactoring to standardize error handling across the entire tool invocation system.
  • This pull request introduces a new, more robust error abstraction layer, impacting how errors are defined, returned, and processed throughout the application.
  • Changes span core server logic, JSON-RPC endpoints, and individual tool implementations, indicating a comprehensive architectural improvement in error management.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request significantly refactors error handling across all tools by introducing the ToolboxError interface, standardizing structured error reporting and consistently applying changes across all Invoke methods. A critical systemic security issue was identified: resource ID parameters (e.g., project, location, cluster) are passed to the underlying GCP API without validation. This vulnerability allows for API path manipulation via path traversal, potentially leading to unauthorized access, especially when the toolbox uses its own service account credentials (ADC). Strict regex validation is recommended for all such parameters. Additionally, the review includes suggestions for improving parameter validation by checking for empty strings, addresses a bug in NewAgentError usage, and proposes improvements for the new ProecessGcpError function, including a typo and a recommendation for a better default error type.

select {
case <-ctx.Done():
return nil, fmt.Errorf("timed out waiting for operation: %w", ctx.Err())
return nil, util.NewAgentError("timed out waiting for operation %s", ctx.Err())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

util.NewAgentError does not format the message string. The %s will be treated as a literal part of the error message. To include the context error, you should pass it as the second argument (cause) to NewAgentError.

Suggested change
return nil, util.NewAgentError("timed out waiting for operation %s", ctx.Err())
return nil, util.NewAgentError("timed out waiting for operation", ctx.Err())

}

return source.CreateInstance(ctx, project, location, cluster, instanceID, instanceType, displayName, nodeCount, string(accessToken))
resp, err := source.CreateInstance(ctx, project, location, cluster, instanceID, instanceType, displayName, nodeCount, string(accessToken))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

The project, location, cluster, and instance parameters are passed to source.CreateInstance without validation, allowing for API path manipulation via path traversal. This could lead to unauthorized access to other AlloyDB resources.

Remediation: Implement strict regex validation for all resource ID parameters.

Comment on lines 230 to 232
if !ok {
return nil, fmt.Errorf("missing 'location' parameter")
return nil, util.NewAgentError("missing 'location' parameter", nil)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The validation for location only checks for presence (!ok) but not for an empty string. Since this is a required parameter, it should not be empty.

Suggested change
if !ok {
return nil, fmt.Errorf("missing 'location' parameter")
return nil, util.NewAgentError("missing 'location' parameter", nil)
}
if !ok || location == "" {
return nil, util.NewAgentError("missing or invalid 'location' parameter", nil)
}

Comment on lines 234 to 236
if !ok {
return nil, fmt.Errorf("missing 'operation' parameter")
return nil, util.NewAgentError("missing 'operation' parameter", nil)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The validation for operation only checks for presence (!ok) but not for an empty string. Since this is a required parameter, it should not be empty.

Suggested change
if !ok {
return nil, fmt.Errorf("missing 'operation' parameter")
return nil, util.NewAgentError("missing 'operation' parameter", nil)
}
if !ok || operation == "" {
return nil, util.NewAgentError("missing or invalid 'operation' parameter", nil)
}

Comment on lines 159 to +161
if !ok {
return nil, fmt.Errorf("invalid 'user' parameter; expected a string")
return nil, util.NewAgentError("invalid 'user' parameter; expected a string", nil)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The validation for user only checks for presence (!ok) but not for an empty string. While this parameter has a default value, if a user explicitly provides an empty string, it will be passed to the underlying API, which is likely invalid. The validation should be strengthened to check for an empty string.

Suggested change
if !ok {
return nil, fmt.Errorf("invalid 'user' parameter; expected a string")
return nil, util.NewAgentError("invalid 'user' parameter; expected a string", nil)
}
if !ok || user == "" {
return nil, util.NewAgentError("invalid or missing 'user' parameter; expected a non-empty string", nil)
}

return &ClientServerError{Msg: msg, Code: code, Cause: cause}
}

func ProecessGcpError(err error) ToolboxError {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a typo in the function name. It should be ProcessGcpError. This should be corrected here and at all call sites.

Suggested change
func ProecessGcpError(err error) ToolboxError {
func ProcessGcpError(err error) ToolboxError {

Comment on lines 154 to 156
if !ok {
return nil, fmt.Errorf("invalid 'network' parameter; expected a string")
return nil, util.NewAgentError("invalid 'network' parameter; expected a string", nil)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The validation for network only checks for presence (!ok) but not for an empty string. While this parameter has a default value, if a user explicitly provides an empty string, it will be passed to the underlying API, which is likely invalid. The validation should be strengthened to check for an empty string.

Suggested change
if !ok {
return nil, fmt.Errorf("invalid 'network' parameter; expected a string")
return nil, util.NewAgentError("invalid 'network' parameter; expected a string", nil)
}
if !ok || network == "" {
return nil, util.NewAgentError("invalid or missing 'network' parameter; expected a non-empty string", nil)
}

@duwenxin99 duwenxin99 requested a review from a team as a code owner February 3, 2026 05:43
@duwenxin99 duwenxin99 requested review from a team as code owners February 3, 2026 06:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants