melib/imap/cache: return NotFound on cache miss

Set error kind to NotFound instead of Bug, since it is possible a
mailbox state is not cached. Also add convenience function
ignore_not_found() that converts NotFound Err Results to Ok(()).

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/443/head
Manos Pitsidianakis 2 months ago
parent b7da1d0f99
commit 91fdef9820
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -59,6 +59,15 @@ pub struct CachedEnvelope {
pub modsequence: Option<ModSequence>,
}
/// 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<Option<()>>;

@ -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 {

@ -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 {

Loading…
Cancel
Save