fix(bot): preserve HTML body content and isolate mailbox poll failures

_extract_body previously discarded real HTML content, replacing it with
a placeholder whenever a multipart email had no text/plain part. Now
falls back to the raw text/html payload before giving up, only using
the placeholder when a message has no text-bearing part at all.

poll_mailboxes also had no error isolation: an unhandled IMAP exception
from any one mailbox would stop the discord.ext.tasks.Loop permanently,
silently killing ingestion for all three mailboxes. Each mailbox's poll
is now wrapped in try/except so one failure doesn't block the others.
This commit is contained in:
pyr0ball 2026-07-13 14:12:46 -07:00
parent f4b57238d2
commit f1bf86a5c9

View file

@ -46,7 +46,10 @@ class EmailIngestCog(commands.Cog):
host = getattr(self.config, host_attr)
user = getattr(self.config, user_attr)
password = getattr(self.config, pass_attr)
await self._poll_one(modality, host, user, password)
try:
await self._poll_one(modality, host, user, password)
except Exception as exc:
print(f"Chorus: failed to poll {modality} mailbox ({host}): {exc} — will retry next cycle")
async def _poll_one(self, modality: str, host: str, user: str, password: str):
seen = self.seen_uids.setdefault(modality, [])
@ -83,10 +86,18 @@ class EmailIngestCog(commands.Cog):
@staticmethod
def _extract_body(msg) -> str:
if msg.is_multipart():
plain_part = None
html_part = None
for part in msg.walk():
if part.get_content_type() == "text/plain":
return part.get_payload(decode=True).decode(errors="replace")
return "(no plain-text body found)"
if part.get_content_type() == "text/plain" and plain_part is None:
plain_part = part.get_payload(decode=True).decode(errors="replace")
elif part.get_content_type() == "text/html" and html_part is None:
html_part = part.get_payload(decode=True).decode(errors="replace")
if plain_part is not None:
return plain_part
if html_part is not None:
return html_part
return "(no text content found)"
return msg.get_payload(decode=True).decode(errors="replace")