feat: Don't ignore receive_imf_inner() errors, try adding partially downloaded message instead (#7196)

Ignoring `receive_imf_inner()` errors, i.e. silently skipping messages on failures, leads to bugs
never fixed. As for temporary I/O errors, ignoring them leads to lost messages, in this case it's
better to bubble up the error and get the IMAP loop stuck. However if there's some logic error, it's
better to show it to the user so that it's more likely reported, and continue receiving messages. To
distinguish these cases, on error, try adding the message as partially downloaded with the error set
to `msgs.error`, this way the user also can retry downloading the message to finally see it if the
problem is fixed.
This commit is contained in:
iequidoo
2025-09-29 14:55:57 -03:00
committed by iequidoo
parent eb0a5fed8e
commit f94b2c3794
7 changed files with 109 additions and 40 deletions

View File

@@ -240,12 +240,12 @@ const MIME_AC_SETUP_FILE: &str = "application/autocrypt-setup";
impl MimeMessage {
/// Parse a mime message.
///
/// If `partial` is set, it contains the full message size in bytes
/// and `body` contains the header only.
/// If `partial` is set, it contains the full message size in bytes and an optional error text
/// for the partially downloaded message, and `body` contains the HEADER only.
pub(crate) async fn from_bytes(
context: &Context,
body: &[u8],
partial: Option<u32>,
partial: Option<(u32, Option<String>)>,
) -> Result<Self> {
let mail = mailparse::parse_mail(body)?;
@@ -612,9 +612,9 @@ impl MimeMessage {
};
match partial {
Some(org_bytes) => {
Some((org_bytes, err)) => {
parser
.create_stub_from_partial_download(context, org_bytes)
.create_stub_from_partial_download(context, org_bytes, err)
.await?;
}
None => match mail {
@@ -634,7 +634,7 @@ impl MimeMessage {
error: Some(format!("Decrypting failed: {err:#}")),
..Default::default()
};
parser.parts.push(part);
parser.do_add_single_part(part);
}
},
};
@@ -1543,7 +1543,7 @@ impl MimeMessage {
Ok(true)
}
fn do_add_single_part(&mut self, mut part: Part) {
pub(crate) fn do_add_single_part(&mut self, mut part: Part) {
if self.was_encrypted() {
part.param.set_int(Param::GuaranteeE2ee, 1);
}