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) => {
|
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) => {
|
Err(e) => {
|
||||||
warn!("Failed to prefetch details for {:?}: {}", mail.subject, e);
|
warn!("Failed to prefetch details for {:?}: {}", mail.subject, e);
|
||||||
|
|||||||
@@ -264,15 +264,30 @@ impl TutaSession {
|
|||||||
&self,
|
&self,
|
||||||
mail: &Mail,
|
mail: &Mail,
|
||||||
) -> Result<Option<MailDetails>, ApiCallError> {
|
) -> Result<Option<MailDetails>, ApiCallError> {
|
||||||
if mail.mailDetails.is_some() {
|
// Tuta stores a mail's body in two different places depending on
|
||||||
match self.logged_in.mail_facade().load_mail_details_blob(mail).await {
|
// 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)),
|
Ok(details) => Ok(Some(details)),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Failed to load mail details blob: {e}");
|
log::error!("Failed to load mail details blob: {e}");
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} 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)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user