-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] Machine-friendly exit codes for error classification #59
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package exitcode | ||
|
|
||
| const ( | ||
| Success = 0 | ||
| General = 1 | ||
| Usage = 2 | ||
| NoStagedChanges = 10 | ||
| NotGitRepo = 11 | ||
| LLMError = 12 | ||
| ) | ||
|
|
||
| type Error struct { | ||
| Code int | ||
| Message string | ||
| Err error | ||
| } | ||
|
|
||
| func (e *Error) Error() string { return e.Message } | ||
| func (e *Error) Unwrap() error { return e.Err } | ||
|
|
||
| func New(code int, msg string, err error) *Error { | ||
| return &Error{Code: code, Message: msg, Err: err} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,8 @@ import ( | |
| "github.com/sashabaranov/go-openai" | ||
| ) | ||
|
|
||
| var ErrLLM = errors.New("LLM error") | ||
|
|
||
| type Options struct { | ||
| Timeout time.Duration | ||
| } | ||
|
|
@@ -99,11 +101,11 @@ func (c *Client) GenerateCommitMessage(prompt string, model string) (string, err | |
| ) | ||
|
|
||
| if err != nil { | ||
| return "", fmt.Errorf("failed to call LLM: %w", err) | ||
| return "", fmt.Errorf("failed to call LLM: %w (%w)", err, ErrLLM) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of multiple For compatibility with Go versions < 1.20, you could wrap only For example: return "", fmt.Errorf("failed to call LLM: %v: %w", err, ErrLLM)This would mean |
||
| } | ||
|
|
||
| if len(resp.Choices) == 0 { | ||
| return "", errors.New("LLM returned empty response") | ||
| return "", fmt.Errorf("LLM returned empty response: %w", ErrLLM) | ||
| } | ||
|
|
||
| return strings.TrimSpace(resp.Choices[0].Message.Content), nil | ||
|
|
@@ -143,11 +145,11 @@ func (c *Client) SuggestVersion(baseVersion string, commits []string, model stri | |
| ) | ||
|
|
||
| if err != nil { | ||
| return "", "", fmt.Errorf("failed to call LLM: %w", err) | ||
| return "", "", fmt.Errorf("failed to call LLM: %w (%w)", err, ErrLLM) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| if len(resp.Choices) == 0 { | ||
| return "", "", errors.New("LLM returned empty response") | ||
| return "", "", fmt.Errorf("LLM returned empty response: %w", ErrLLM) | ||
| } | ||
|
|
||
| version, reason, err := parseVersionSuggestion(resp.Choices[0].Message.Content) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,19 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "errors" | ||
| "os" | ||
|
|
||
| "github.com/samzong/gmc/cmd" | ||
| "github.com/samzong/gmc/internal/exitcode" | ||
| ) | ||
|
|
||
| func main() { | ||
| if err := cmd.Execute(); err != nil { | ||
| os.Exit(1) | ||
| var exitErr *exitcode.Error | ||
| if errors.As(err, &exitErr) { | ||
| os.Exit(exitErr.Code) | ||
| } | ||
| os.Exit(exitcode.General) | ||
| } | ||
| } |
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.
To ensure consistent error message formatting across all commands, unclassified errors from the
tagcommand should also be wrapped inuserFacingError, similar to how the root command handles them. This will provide a uniform experience for users, with errors prefixed bygmc:.After making this change, please also ensure all error return paths in
runTagCommanduse this wrapper for consistency (e.g., the one at line 70 seems to have been missed).