From ec5c43163b73c568c34091299d7df492f2613d3d Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Sun, 1 Mar 2026 14:10:24 +0000 Subject: [PATCH] refactor(cmd): improve error handling in commands and tests - Add error checking for filepath.Walk and fmt.Scanln in agent.go - Ignore MkdirAll error in chat.go, add checks in chat_test.go - Add Scanln error handling in commit.go - Capture and exit on completion generation errors in completion.go - Add WriteFile error checks in edit_test.go --- cmd/agent.go | 16 +++++++++++++--- cmd/chat.go | 2 +- cmd/chat_test.go | 8 ++++++-- cmd/commit.go | 5 ++++- cmd/completion.go | 12 ++++++++---- cmd/edit_test.go | 8 ++++++-- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/cmd/agent.go b/cmd/agent.go index a9057a4..c8a6166 100644 --- a/cmd/agent.go +++ b/cmd/agent.go @@ -27,7 +27,7 @@ var agentCmd = &cobra.Command{ color.Yellow("🔍 Agent mode activated. Scanning project...") var files []string - filepath.Walk(".", func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error { if err != nil || info.IsDir() { return err } @@ -36,6 +36,10 @@ var agentCmd = &cobra.Command{ } return nil }) + if err != nil { + color.Red("Failed to scan project: %v", err) + os.Exit(1) + } if len(files) == 0 { color.Yellow("No .go files found.") @@ -54,7 +58,10 @@ var agentCmd = &cobra.Command{ fmt.Print("\nProceed with changes? (y/n): ") var confirm string - fmt.Scanln(&confirm) + if _, err := fmt.Scanln(&confirm); err != nil { + color.Red("Failed to read input: %v", err) + return + } if confirm != "y" && confirm != "Y" { color.Yellow("Aborted.") return @@ -91,7 +98,10 @@ var agentCmd = &cobra.Command{ if !applyAll { fmt.Print("\nApply this file? (y/n/a = all remaining): ") var answer string - fmt.Scanln(&answer) + if _, err := fmt.Scanln(&answer); err != nil { + color.Yellow("Skipped %s (failed to read input)", file) + continue + } answer = strings.ToLower(strings.TrimSpace(answer)) if answer == "a" { diff --git a/cmd/chat.go b/cmd/chat.go index 67bd176..4a555cc 100644 --- a/cmd/chat.go +++ b/cmd/chat.go @@ -54,7 +54,7 @@ func getChatHistoryFile() string { home = "." } histDir := filepath.Join(home, ".config", "grokkit") - os.MkdirAll(histDir, 0755) + _ = os.MkdirAll(histDir, 0755) // Ignore error, WriteFile will catch it return filepath.Join(histDir, "chat_history.json") } diff --git a/cmd/chat_test.go b/cmd/chat_test.go index df1c54a..b81bd61 100644 --- a/cmd/chat_test.go +++ b/cmd/chat_test.go @@ -82,9 +82,13 @@ func TestLoadChatHistory_InvalidJSON(t *testing.T) { // Create invalid JSON file histDir := filepath.Join(tmpDir, ".config", "grokkit") - os.MkdirAll(histDir, 0755) + if err := os.MkdirAll(histDir, 0755); err != nil { + t.Fatalf("MkdirAll() error: %v", err) + } histFile := filepath.Join(histDir, "chat_history.json") - os.WriteFile(histFile, []byte("invalid json{{{"), 0644) + if err := os.WriteFile(histFile, []byte("invalid json{{{"), 0644); err != nil { + t.Fatalf("WriteFile() error: %v", err) + } history := loadChatHistory() if history != nil { diff --git a/cmd/commit.go b/cmd/commit.go index c8b4b0c..716486a 100644 --- a/cmd/commit.go +++ b/cmd/commit.go @@ -38,7 +38,10 @@ var commitCmd = &cobra.Command{ color.Cyan("\nProposed commit message:\n%s", msg) var confirm string color.Yellow("Commit with this message? (y/n): ") - fmt.Scanln(&confirm) + if _, err := fmt.Scanln(&confirm); err != nil { + color.Red("Failed to read input: %v", err) + return + } if confirm != "y" && confirm != "Y" { color.Yellow("Aborted.") return diff --git a/cmd/completion.go b/cmd/completion.go index 4561833..20fca67 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -49,15 +49,19 @@ PowerShell: ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { + var err error switch args[0] { case "bash": - cmd.Root().GenBashCompletion(os.Stdout) + err = cmd.Root().GenBashCompletion(os.Stdout) case "zsh": - cmd.Root().GenZshCompletion(os.Stdout) + err = cmd.Root().GenZshCompletion(os.Stdout) case "fish": - cmd.Root().GenFishCompletion(os.Stdout, true) + err = cmd.Root().GenFishCompletion(os.Stdout, true) case "powershell": - cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + err = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + } + if err != nil { + os.Exit(1) } }, } diff --git a/cmd/edit_test.go b/cmd/edit_test.go index 72adab6..6d2776f 100644 --- a/cmd/edit_test.go +++ b/cmd/edit_test.go @@ -17,7 +17,9 @@ func TestEditCommand(t *testing.T) { defer os.Remove(tmpfile.Name()) original := []byte("package main\n\nfunc hello() {}\n") - os.WriteFile(tmpfile.Name(), original, 0644) + if err := os.WriteFile(tmpfile.Name(), original, 0644); err != nil { + t.Fatal(err) + } // Test the core editing logic directly (non-interactive) instruction := "add a comment at the top" @@ -32,7 +34,9 @@ func TestEditCommand(t *testing.T) { newContent := grok.CleanCodeResponse(raw) // Apply the result (this is what the real command does after confirmation) - os.WriteFile(tmpfile.Name(), []byte(newContent), 0644) + if err := os.WriteFile(tmpfile.Name(), []byte(newContent), 0644); err != nil { + t.Fatal(err) + } // Verify content, _ := os.ReadFile(tmpfile.Name())