From dc1b06cbdc6721247b06db3aba6d193242980350 Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 7 Jun 2026 00:13:46 +0200 Subject: [PATCH 1/2] fix(imap): do not bubble up errors in IMAP candidate loop Network errors such as timeouts should not break out of the loop by bubbling up errors. There may be more candidates to try, breaking out of the loop skips trying them. --- src/imap.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index 1533299932..cf156afeed 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -395,18 +395,30 @@ impl Imap { match login_res { Ok(mut session) => { - let capabilities = determine_capabilities(&mut session).await?; + let capabilities = match determine_capabilities(&mut session).await { + Ok(capabilities) => capabilities, + Err(err) => { + warn!(context, "Failed to determine capabilities: {err:#}."); + continue; + } + }; let resync_request_sender = self.resync_request_sender.clone(); let session = if capabilities.can_compress { info!(context, "Enabling IMAP compression."); - let compressed_session = session + let compressed_session = match session .compress(|s| { let session_stream: Box = Box::new(s); session_stream }) .await - .context("Failed to enable IMAP compression")?; + { + Ok(compressed_session) => compressed_session, + Err(err) => { + warn!(context, "Failed to enable IMAP compression: {err:#}."); + continue; + } + }; Session::new( compressed_session, capabilities, From 0462e12921168b0216e00f4df97351d1b5da49f0 Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 16 Jul 2026 07:34:03 +0000 Subject: [PATCH 2/2] refactor: label the loop iterating over the candidates The loop is large, so having an explicit label makes it easier to understand what the "continue" statement does. --- src/imap.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index cf156afeed..29acf6e8c5 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -350,7 +350,7 @@ impl Imap { let login_params = prioritize_server_login_params(&context.sql, &self.lp, "imap").await?; let mut first_error = None; - for lp in login_params { + 'candidate: for lp in login_params { info!(context, "IMAP trying to connect to {}.", lp.connection); let connection_candidate = lp.connection.clone(); let client = match Client::connect( @@ -366,7 +366,7 @@ impl Imap { Err(err) => { warn!(context, "{err:#}."); first_error.get_or_insert(err); - continue; + continue 'candidate; } }; @@ -399,7 +399,7 @@ impl Imap { Ok(capabilities) => capabilities, Err(err) => { warn!(context, "Failed to determine capabilities: {err:#}."); - continue; + continue 'candidate; } }; let resync_request_sender = self.resync_request_sender.clone(); @@ -416,7 +416,7 @@ impl Imap { Ok(compressed_session) => compressed_session, Err(err) => { warn!(context, "Failed to enable IMAP compression: {err:#}."); - continue; + continue 'candidate; } }; Session::new(