-
Notifications
You must be signed in to change notification settings - Fork 1.2k
refactor(tools): refactor all Tools to return ToolboxError #2403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: err-api
Are you sure you want to change the base?
Conversation
Summary of ChangesHello @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 Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this 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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| if !ok { | ||
| return nil, fmt.Errorf("missing 'location' parameter") | ||
| return nil, util.NewAgentError("missing 'location' parameter", nil) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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) | |
| } |
| if !ok { | ||
| return nil, fmt.Errorf("missing 'operation' parameter") | ||
| return nil, util.NewAgentError("missing 'operation' parameter", nil) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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) | |
| } |
| if !ok { | ||
| return nil, fmt.Errorf("invalid 'user' parameter; expected a string") | ||
| return nil, util.NewAgentError("invalid 'user' parameter; expected a string", nil) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if !ok { | ||
| return nil, fmt.Errorf("invalid 'network' parameter; expected a string") | ||
| return nil, util.NewAgentError("invalid 'network' parameter; expected a string", nil) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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) | |
| } |
util.ProcessGcpErrorfor GCP sourcesutil.ProcessGeneralErrorfor all other sources.