mirror of
https://github.com/spartanz51/tutabridge.git
synced 2026-06-24 10:54:32 +02:00
Load draft bodies and stop spamming "No details for mail"
`load_mail_details_impl` now mirrors the TS `loadMailDetails` router: when `mail.mailDetailsDraft` is set, call the new `MailFacade::load_mail_details_draft` (sdk-mail-draft-details); when `mail.mailDetails` is set, keep the existing blob path; otherwise return `Ok(None)` — the legacy/malformed leaf the prefetch loop has to handle anyway. Practical effect: the ~88 drafts on the test account that previously logged "No details for mail" on every store change now decrypt their body normally and surface it through IMAP FETCH. The `Ok(None)` branch in `prefetch_details` was the secondary cause of the log spam — with the prefetch loop now event-driven (Phase 2.5), every `MailStore` bump re-queued the same 88 drafts because `has_eml` stayed false. Persist a headers-only `.eml` and `mark_has_details = 1` on that branch so the row is considered done; the next sweep skips it, and the client at least gets the headers for a mail whose body we genuinely cannot locate.
This commit is contained in:
@@ -615,7 +615,20 @@ async fn prefetch_details(
|
||||
}
|
||||
}
|
||||
Ok(None) => {
|
||||
debug!("No details for mail {:?}", mail.subject);
|
||||
// The mail references neither a `MailDetailsBlob` nor a
|
||||
// `MailDetailsDraft` (legacy / malformed). Persist a
|
||||
// headers-only `.eml` and mark the row done so we don't
|
||||
// re-attempt every prefetch sweep.
|
||||
let rfc2822 = mail_to_rfc2822(mail, None);
|
||||
if let Some(id) = mail._id.as_ref() {
|
||||
let eid = id.element_id.to_string();
|
||||
if let Err(e) = local_store.write_eml(&eid, &rfc2822) {
|
||||
warn!("Failed to cache headers-only eml {}: {}", eid, e);
|
||||
}
|
||||
if let Err(e) = local_store.mark_has_details(&eid) {
|
||||
warn!("Failed to mark has_details {}: {}", eid, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Failed to prefetch details for {:?}: {}", mail.subject, e);
|
||||
|
||||
@@ -264,15 +264,30 @@ impl TutaSession {
|
||||
&self,
|
||||
mail: &Mail,
|
||||
) -> Result<Option<MailDetails>, ApiCallError> {
|
||||
if mail.mailDetails.is_some() {
|
||||
match self.logged_in.mail_facade().load_mail_details_blob(mail).await {
|
||||
// Tuta stores a mail's body in two different places depending on
|
||||
// whether the mail is received or a draft. Match the TS routing
|
||||
// (`isDraft(mail) ? loadMailDetailsDraft : loadMailDetailsBlob`).
|
||||
let mail_facade = self.logged_in.mail_facade();
|
||||
if mail.mailDetailsDraft.is_some() {
|
||||
match mail_facade.load_mail_details_draft(mail).await {
|
||||
Ok(details) => Ok(Some(details)),
|
||||
Err(e) => {
|
||||
log::error!("Failed to load mail details draft: {e}");
|
||||
Err(e)
|
||||
},
|
||||
}
|
||||
} else if mail.mailDetails.is_some() {
|
||||
match mail_facade.load_mail_details_blob(mail).await {
|
||||
Ok(details) => Ok(Some(details)),
|
||||
Err(e) => {
|
||||
log::error!("Failed to load mail details blob: {e}");
|
||||
Err(e)
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// Legacy mail without either reference — body lives nowhere we
|
||||
// know how to read. The prefetch layer treats `Ok(None)` as
|
||||
// "render with headers only, do not retry".
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user