From dcf6ffef129004ed5fadb4c0b0eb3600e08c9f1b Mon Sep 17 00:00:00 2001 From: link2xt Date: Sat, 23 Dec 2023 01:33:53 +0000 Subject: [PATCH] fix(imap): fail fast on LIST errors async-imap returns infinite stream of errors in case of EOF or timeout on the input stream, so attempting to skip and log errors results in busy loop similar to this: 2023-12-22T13:07:35.751Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.751Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.751Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.751Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.752Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.752Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.752Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.752Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.753Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.754Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" 2023-12-22T13:07:35.754Z core/event WARNING "" 2 "/__w/deltachat-core-rust/deltachat-core-rust/src/imap/scan_folders.rs:112: list_folders() can't get folder: io: timed out: timed out" To avoid busy loop, fail fast on first error and bubble it up instead of trying to recover. --- src/imap.rs | 2 +- src/imap/scan_folders.rs | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index 02a74c46a..81a31d3d4 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -994,7 +994,7 @@ impl Imap { self.prepare(context).await?; let all_folders = self - .list_folders(context) + .list_folders() .await .context("listing folders for resync")?; for folder in all_folders { diff --git a/src/imap/scan_folders.rs b/src/imap/scan_folders.rs index 8b63098b8..714c961f3 100644 --- a/src/imap/scan_folders.rs +++ b/src/imap/scan_folders.rs @@ -1,7 +1,7 @@ use std::{collections::BTreeMap, time::Instant}; use anyhow::{Context as _, Result}; -use futures::stream::StreamExt; +use futures::TryStreamExt; use super::{get_folder_meaning_by_attrs, get_folder_meaning_by_name}; use crate::config::Config; @@ -27,7 +27,7 @@ impl Imap { info!(context, "Starting full folder scan"); self.prepare(context).await?; - let folders = self.list_folders(context).await?; + let folders = self.list_folders().await?; let watched_folders = get_watched_folders(context).await?; let mut folder_configs = BTreeMap::new(); @@ -98,21 +98,15 @@ impl Imap { } /// Returns the names of all folders on the IMAP server. - pub async fn list_folders( - self: &mut Imap, - context: &Context, - ) -> Result> { + pub async fn list_folders(self: &mut Imap) -> Result> { let session = self.session.as_mut(); let session = session.context("No IMAP connection")?; let list = session .list(Some(""), Some("*")) .await? - .filter_map(|f| async { - f.context("list_folders() can't get folder") - .log_err(context) - .ok() - }); - Ok(list.collect().await) + .try_collect() + .await?; + Ok(list) } }