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:
parent
f4b57238d2
commit
f1bf86a5c9
1 changed files with 15 additions and 4 deletions
|
|
@ -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")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue