diff options
author | Robin Jarry <robin@jarry.cc> | 2024-05-17 16:03:04 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-07-01 00:09:16 +0200 |
commit | 588776f42574567f907c190a5ff089256b21e598 (patch) | |
tree | 011e78e52d4e70afeb6e11ffe315eb5aa45dc2e2 /worker | |
parent | 0efcf2b3b08de22bcd5994a671c2b276db3488eb (diff) | |
download | aerc-588776f42574567f907c190a5ff089256b21e598.tar.gz |
imap: report errors from server
Avoid eternal spinner on the message list when the imap server
advertises some message UIDs but fails to provide their headers when
aerc asks from them.
When an error occurs, or if some UIDs are not returned, make sure to
report the errors to the message list UI.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Reviewed-by: Tristan Partin <tristan@partin.io>
Diffstat (limited to 'worker')
-rw-r--r-- | worker/imap/fetch.go | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go index 46ca8a5f..202038fe 100644 --- a/worker/imap/fetch.go +++ b/worker/imap/fetch.go @@ -239,44 +239,54 @@ func (imapw *IMAPWorker) handleFetchMessages( msg types.WorkerMessage, uids []uint32, items []imap.FetchItem, procFunc func(*imap.Message) error, ) { - var err error messages := make(chan *imap.Message) - done := make(chan []error) + done := make(chan struct{}) + + missingUids := make(map[uint32]bool) + for _, uid := range uids { + missingUids[uid] = true + } go func() { defer log.PanicHandler() - var reterr []error - for msg := range messages { - err := procFunc(msg) + for _msg := range messages { + delete(missingUids, _msg.Uid) + err := procFunc(_msg) if err != nil { - log.Errorf("failed to process message <%d>: %v", msg.Uid, err) - reterr = append(reterr, err) + log.Errorf("failed to process message <%d>: %v", _msg.Uid, err) + imapw.worker.PostMessage(&types.MessageInfo{ + Message: types.RespondTo(msg), + Info: &models.MessageInfo{ + Uid: _msg.Uid, + Error: err, + }, + }, nil) } } - done <- reterr + close(done) }() - emitErr := func(err error) { + set := toSeqSet(uids) + if err := imapw.client.UidFetch(set, items, messages); err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) - } - - set := toSeqSet(uids) - if err = imapw.client.UidFetch(set, items, messages); err != nil { - emitErr(err) return } - if errs := <-done; len(errs) != 0 { - err = errs[0] - if len(errs) > 1 { - err = fmt.Errorf("parsing of %d messages failed", len(errs)) - } - emitErr(err) - return + <-done + + for uid := range missingUids { + imapw.worker.PostMessage(&types.MessageInfo{ + Message: types.RespondTo(msg), + Info: &models.MessageInfo{ + Uid: uid, + Error: fmt.Errorf("invalid response from server (detailed error in log)"), + }, + }, nil) } + imapw.worker.PostMessage( &types.Done{Message: types.RespondTo(msg)}, nil) } |