Remove os.Exit() from library code (gt-fm75)

Refactor to return errors instead of calling os.Exit() directly:
- Add SilentExitError type for commands that signal status via exit code
- Update mail.go runMailPeek() and runMailCheck() to return errors
- Change Execute() to return int exit code instead of calling os.Exit()
- Move os.Exit() call to main() where it belongs

This improves testability, enables graceful shutdown, and follows Go
conventions for library code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-30 10:53:10 -08:00
parent 7fdee48807
commit 637f38edca
4 changed files with 53 additions and 17 deletions

View File

@@ -579,23 +579,20 @@ func runMailPeek(cmd *cobra.Command, args []string) error {
// All mail uses town beads (two-level architecture)
workDir, err := findMailWorkDir()
if err != nil {
os.Exit(1) // Silent exit - no workspace
return nil
return NewSilentExit(1) // Silent exit - no workspace
}
// Get mailbox
router := mail.NewRouter(workDir)
mailbox, err := router.GetMailbox(address)
if err != nil {
os.Exit(1) // Silent exit - can't access mailbox
return nil
return NewSilentExit(1) // Silent exit - can't access mailbox
}
// Get unread messages
messages, err := mailbox.ListUnread()
if err != nil || len(messages) == 0 {
os.Exit(1) // Silent exit - no unread
return nil
return NewSilentExit(1) // Silent exit - no unread
}
// Show first unread message
@@ -923,12 +920,10 @@ func runMailCheck(cmd *cobra.Command, args []string) error {
// Normal mode
if unread > 0 {
fmt.Printf("%s %d unread message(s)\n", style.Bold.Render("📬"), unread)
os.Exit(0)
} else {
fmt.Println("No new mail")
os.Exit(1)
return NewSilentExit(0)
}
return nil
fmt.Println("No new mail")
return NewSilentExit(1)
}
func runMailThread(cmd *cobra.Command, args []string) error {