refactor(cmd): improve error handling in commands and tests
Some checks failed
CI / Test (push) Successful in 26s
CI / Lint (push) Failing after 14s
CI / Build (push) Failing after 31s

- 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
This commit is contained in:
Greg Gauthier 2026-03-01 14:10:24 +00:00
parent 47e7b51d1e
commit ec5c43163b
6 changed files with 38 additions and 13 deletions

View File

@ -27,7 +27,7 @@ var agentCmd = &cobra.Command{
color.Yellow("🔍 Agent mode activated. Scanning project...") color.Yellow("🔍 Agent mode activated. Scanning project...")
var files []string 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() { if err != nil || info.IsDir() {
return err return err
} }
@ -36,6 +36,10 @@ var agentCmd = &cobra.Command{
} }
return nil return nil
}) })
if err != nil {
color.Red("Failed to scan project: %v", err)
os.Exit(1)
}
if len(files) == 0 { if len(files) == 0 {
color.Yellow("No .go files found.") color.Yellow("No .go files found.")
@ -54,7 +58,10 @@ var agentCmd = &cobra.Command{
fmt.Print("\nProceed with changes? (y/n): ") fmt.Print("\nProceed with changes? (y/n): ")
var confirm string 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" { if confirm != "y" && confirm != "Y" {
color.Yellow("Aborted.") color.Yellow("Aborted.")
return return
@ -91,7 +98,10 @@ var agentCmd = &cobra.Command{
if !applyAll { if !applyAll {
fmt.Print("\nApply this file? (y/n/a = all remaining): ") fmt.Print("\nApply this file? (y/n/a = all remaining): ")
var answer string 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)) answer = strings.ToLower(strings.TrimSpace(answer))
if answer == "a" { if answer == "a" {

View File

@ -54,7 +54,7 @@ func getChatHistoryFile() string {
home = "." home = "."
} }
histDir := filepath.Join(home, ".config", "grokkit") 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") return filepath.Join(histDir, "chat_history.json")
} }

View File

@ -82,9 +82,13 @@ func TestLoadChatHistory_InvalidJSON(t *testing.T) {
// Create invalid JSON file // Create invalid JSON file
histDir := filepath.Join(tmpDir, ".config", "grokkit") 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") 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() history := loadChatHistory()
if history != nil { if history != nil {

View File

@ -38,7 +38,10 @@ var commitCmd = &cobra.Command{
color.Cyan("\nProposed commit message:\n%s", msg) color.Cyan("\nProposed commit message:\n%s", msg)
var confirm string var confirm string
color.Yellow("Commit with this message? (y/n): ") 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" { if confirm != "y" && confirm != "Y" {
color.Yellow("Aborted.") color.Yellow("Aborted.")
return return

View File

@ -49,15 +49,19 @@ PowerShell:
ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var err error
switch args[0] { switch args[0] {
case "bash": case "bash":
cmd.Root().GenBashCompletion(os.Stdout) err = cmd.Root().GenBashCompletion(os.Stdout)
case "zsh": case "zsh":
cmd.Root().GenZshCompletion(os.Stdout) err = cmd.Root().GenZshCompletion(os.Stdout)
case "fish": case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true) err = cmd.Root().GenFishCompletion(os.Stdout, true)
case "powershell": case "powershell":
cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) err = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
}
if err != nil {
os.Exit(1)
} }
}, },
} }

View File

@ -17,7 +17,9 @@ func TestEditCommand(t *testing.T) {
defer os.Remove(tmpfile.Name()) defer os.Remove(tmpfile.Name())
original := []byte("package main\n\nfunc hello() {}\n") 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) // Test the core editing logic directly (non-interactive)
instruction := "add a comment at the top" instruction := "add a comment at the top"
@ -32,7 +34,9 @@ func TestEditCommand(t *testing.T) {
newContent := grok.CleanCodeResponse(raw) newContent := grok.CleanCodeResponse(raw)
// Apply the result (this is what the real command does after confirmation) // 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 // Verify
content, _ := os.ReadFile(tmpfile.Name()) content, _ := os.ReadFile(tmpfile.Name())