diff --git a/melib/src/imap/cache.rs b/melib/src/imap/cache.rs index 1c51501c..0905711d 100644 --- a/melib/src/imap/cache.rs +++ b/melib/src/imap/cache.rs @@ -59,6 +59,15 @@ pub struct CachedEnvelope { pub modsequence: Option, } +/// Helper function for ignoring cache misses with +/// `.or_else(ignore_not_found)?`. +pub fn ignore_not_found(err: Error) -> Result<()> { + if matches!(err.kind, ErrorKind::NotFound) { + return Ok(()); + } + Err(err) +} + pub trait ImapCache: Send + std::fmt::Debug { fn reset(&mut self) -> Result<()>; fn mailbox_state(&mut self, mailbox_hash: MailboxHash) -> Result>; diff --git a/melib/src/imap/cache/sqlite3_cache.rs b/melib/src/imap/cache/sqlite3_cache.rs index cae26b75..2b40aef1 100644 --- a/melib/src/imap/cache/sqlite3_cache.rs +++ b/melib/src/imap/cache/sqlite3_cache.rs @@ -421,7 +421,7 @@ impl ImapCache for Sqlite3Cache { .cloned() .unwrap_or_default(); if self.mailbox_state(mailbox_hash)?.is_none() { - return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::Bug)); + return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } let Self { ref mut connection, @@ -479,7 +479,7 @@ impl ImapCache for Sqlite3Cache { flags: SmallVec<[FlagOp; 8]>, ) -> Result<()> { if self.mailbox_state(mailbox_hash)?.is_none() { - return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::Bug)); + return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } let Self { ref mut connection, @@ -537,7 +537,7 @@ impl ImapCache for Sqlite3Cache { refresh_events: &[(UID, RefreshEvent)], ) -> Result<()> { if self.mailbox_state(mailbox_hash)?.is_none() { - return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::Bug)); + return Err(Error::new("Mailbox is not in cache").set_kind(ErrorKind::NotFound)); } { let Self { diff --git a/melib/src/imap/watch.rs b/melib/src/imap/watch.rs index 15ae0660..11f41b8b 100644 --- a/melib/src/imap/watch.rs +++ b/melib/src/imap/watch.rs @@ -23,7 +23,7 @@ use std::sync::Arc; use imap_codec::imap_types::search::SearchKey; use super::*; -use crate::backends::SpecialUsageMailbox; +use crate::{backends::SpecialUsageMailbox, imap::cache::ignore_not_found}; /// Arguments for IMAP watching functions pub struct ImapWatchKit { @@ -91,7 +91,9 @@ pub async fn idle(kit: ImapWatchKit) -> Result<()> { if let Some(v) = uidvalidities.get(&mailbox_hash) { if *v != select_response.uidvalidity { if let Ok(Some(mut cache_handle)) = uid_store.cache_handle() { - cache_handle.clear(mailbox_hash, &select_response)?; + cache_handle + .clear(mailbox_hash, &select_response) + .or_else(ignore_not_found)?; } conn.add_refresh_event(RefreshEvent { account_hash: uid_store.account_hash, @@ -221,7 +223,9 @@ pub async fn examine_updates( if let Some(v) = uidvalidities.get(&mailbox_hash) { if *v != select_response.uidvalidity { if let Ok(Some(mut cache_handle)) = cache_handle { - cache_handle.clear(mailbox_hash, &select_response)?; + cache_handle + .clear(mailbox_hash, &select_response) + .or_else(ignore_not_found)?; } conn.add_refresh_event(RefreshEvent { account_hash: uid_store.account_hash, @@ -372,16 +376,15 @@ pub async fn examine_updates( } } if let Ok(Some(mut cache_handle)) = cache_handle { - if cache_handle.mailbox_state(mailbox_hash)?.is_some() { - cache_handle - .insert_envelopes(mailbox_hash, &v) - .chain_err_summary(|| { - format!( - "Could not save envelopes in cache for mailbox {}", - mailbox.imap_path() - ) - })?; - } + cache_handle + .insert_envelopes(mailbox_hash, &v) + .or_else(ignore_not_found) + .chain_err_summary(|| { + format!( + "Could not save envelopes in cache for mailbox {}", + mailbox.imap_path() + ) + })?; } for FetchResponse { uid, envelope, .. } in v {