From 01f80721e283086cd122879cb2c9f3bb95b274d7 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 16 Sep 2022 14:41:07 -0500 Subject: [PATCH] msgstore: post MessageInfo on erroneous fetch When errors occur during a fetch header request, the requested headers are deleted from pending and no information is given to the UI. Spinners keep spinning, and ultimately as the view is refreshed, the headers are fetched again. This can lead to infinite loops, and extremely long logs. Update the store with a MessageInfo message when an error is received. Have the UI display that the header couldn't be fetched in the message list. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- lib/format/format.go | 4 ++++ lib/msgstore.go | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/format/format.go b/lib/format/format.go index 42dd34a..055e2c7 100644 --- a/lib/format/format.go +++ b/lib/format/format.go @@ -83,6 +83,10 @@ func ParseMessageFormat(format string, timeFmt string, thisDayTimeFmt string, thisWeekTimeFmt string, thisYearTimeFmt string, ctx Ctx) ( string, []interface{}, error, ) { + if ctx.MsgInfo.Error != nil { + return "", nil, + errors.New("(unable to fetch header)") + } retval := make([]byte, 0, len(format)) var args []interface{} diff --git a/lib/msgstore.go b/lib/msgstore.go index 33c2439..a545f62 100644 --- a/lib/msgstore.go +++ b/lib/msgstore.go @@ -112,8 +112,9 @@ func (store *MessageStore) FetchHeaders(uids []uint32, } if len(toFetch) > 0 { store.worker.PostAction(&types.FetchMessageHeaders{Uids: toFetch}, func(msg types.WorkerMessage) { - if _, ok := msg.(*types.Error); ok { + if msg, ok := msg.(*types.Error); ok { for _, uid := range toFetch { + store.postInvalidMessageInfo(uid, msg.Error) delete(store.pendingHeaders, uid) } } @@ -124,6 +125,17 @@ func (store *MessageStore) FetchHeaders(uids []uint32, } } +func (store *MessageStore) postInvalidMessageInfo(uid uint32, err error) { + logging.Errorf("Unable to fetch header %d: %w", uid, err) + info := &models.MessageInfo{ + Envelope: &models.Envelope{}, + Flags: []models.Flag{models.SeenFlag}, + Uid: uid, + Error: err, + } + store.Update(&types.MessageInfo{Info: info}) +} + func (store *MessageStore) FetchFull(uids []uint32, cb func(*types.FullMessage)) { // TODO: this could be optimized by pre-allocating toFetch and trimming it // at the end. In practice we expect to get most messages back in one frame.