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 <noreply@anthropic.com>
This commit is contained in:
Harry Culpan 2026-06-30 18:30:27 -04:00
parent c509641f59
commit 3684baa2f5

View file

@ -64,12 +64,17 @@ func fetchEmails(imapClient *client.Client) ([]Email, error) {
// Fetch the required message attributes // Fetch the required message attributes
messages := make(chan *imap.Message, 10) messages := make(chan *imap.Message, 10)
fetchErr := make(chan error, 1)
section := &imap.BodySectionName{} section := &imap.BodySectionName{}
items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope} items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope}
go func() { go func() {
if err := imapClient.Fetch(seqSet, items, messages); err != nil { fetchErr <- imapClient.Fetch(seqSet, items, messages)
log.Fatal("Fetch error: " + err.Error()) }()
// 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) result = append(result, *email)
} }
if err := <-fetchErr; err != nil {
return result, fmt.Errorf("fetch error: %w", err)
}
} }
return result, nil return result, nil