diff --git a/src/email_client.py b/src/email_client.py index 1b7df02..539a6c2 100644 --- a/src/email_client.py +++ b/src/email_client.py @@ -105,7 +105,6 @@ def _login_and_prepare(account: EmailAccount, timeout: int = 30): return conn -@retry() def fetch_unseen_emails(account: EmailAccount) -> list[Email]: conn = _login_and_prepare(account) @@ -116,7 +115,6 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]: for uid in uids: try: - # 先查大小,大邮件用 PEEK 避免长时间阻塞导致连接断开被标已读 _, size_data = conn.uid("FETCH", uid, "(RFC822.SIZE)") size = 0 if size_data[0]: @@ -125,9 +123,8 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]: size = int(m.group(1)) large = size > 200_000 if large: - logger.info("UID %s 大邮件 (%d bytes),用 PEEK 截断处理", uid, size) + logger.info("UID %s 大邮件 (%d bytes),用 PEEK 拉取", uid, size) - # 大邮件用 PEEK 拉取,不触发服务器标记已读;小邮件正常拉 fetch_cmd = "BODY.PEEK[]" if large else "RFC822" _, msg_data = conn.uid("FETCH", uid, fetch_cmd) if msg_data[0] is None: @@ -148,10 +145,22 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]: emails.append(Email(uid=uid, subject=subject, sender=sender, recipient=recipient, body=body, date=date_str, reply_to=reply_to, account_email=account.username)) except Exception as e: - logger.error("UID %s FETCH 失败,跳过: %s", uid, e) + logger.error("UID %s FETCH 失败,跳过并重建连接: %s", uid, e) + try: + conn.logout() + except Exception: + pass + try: + conn = _login_and_prepare(account) + except Exception as e2: + logger.error("重建连接失败: %s", e2) + break continue - conn.logout() + try: + conn.logout() + except Exception: + pass logger.info("共获取 %d 封新邮件", len(emails)) return emails