From 3684baa2f57820f4f4fb0893d33a88bd02c47093 Mon Sep 17 00:00:00 2001 From: Harry Culpan Date: Tue, 30 Jun 2026 18:30:27 -0400 Subject: [PATCH] Replace log.Fatal in IMAP fetch goroutine with error channel log.Fatal called os.Exit from a goroutine, bypassing deferred cleanup and crashing the process on any transient fetch error. Errors now propagate back to the caller via a buffered channel. Also adds a drain defer so the goroutine can always exit if the consumer returns early. Co-Authored-By: Claude Sonnet 4.6 --- pkg/email/fetch.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/email/fetch.go b/pkg/email/fetch.go index c338cc5..d8080e2 100644 --- a/pkg/email/fetch.go +++ b/pkg/email/fetch.go @@ -64,12 +64,17 @@ func fetchEmails(imapClient *client.Client) ([]Email, error) { // Fetch the required message attributes messages := make(chan *imap.Message, 10) + fetchErr := make(chan error, 1) section := &imap.BodySectionName{} items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope} go func() { - if err := imapClient.Fetch(seqSet, items, messages); err != nil { - log.Fatal("Fetch error: " + err.Error()) + fetchErr <- imapClient.Fetch(seqSet, items, messages) + }() + + // Drain the channel on early return so the goroutine can always exit. + defer func() { + for range messages { } }() @@ -98,6 +103,10 @@ func fetchEmails(imapClient *client.Client) ([]Email, error) { ) result = append(result, *email) } + + if err := <-fetchErr; err != nil { + return result, fmt.Errorf("fetch error: %w", err) + } } return result, nil