fix: per-email error handling with connection rebuild, remove @retry on fetch
This commit is contained in:
@@ -105,7 +105,6 @@ def _login_and_prepare(account: EmailAccount, timeout: int = 30):
|
|||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
|
||||||
@retry()
|
|
||||||
def fetch_unseen_emails(account: EmailAccount) -> list[Email]:
|
def fetch_unseen_emails(account: EmailAccount) -> list[Email]:
|
||||||
conn = _login_and_prepare(account)
|
conn = _login_and_prepare(account)
|
||||||
|
|
||||||
@@ -116,7 +115,6 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]:
|
|||||||
|
|
||||||
for uid in uids:
|
for uid in uids:
|
||||||
try:
|
try:
|
||||||
# 先查大小,大邮件用 PEEK 避免长时间阻塞导致连接断开被标已读
|
|
||||||
_, size_data = conn.uid("FETCH", uid, "(RFC822.SIZE)")
|
_, size_data = conn.uid("FETCH", uid, "(RFC822.SIZE)")
|
||||||
size = 0
|
size = 0
|
||||||
if size_data[0]:
|
if size_data[0]:
|
||||||
@@ -125,9 +123,8 @@ def fetch_unseen_emails(account: EmailAccount) -> list[Email]:
|
|||||||
size = int(m.group(1))
|
size = int(m.group(1))
|
||||||
large = size > 200_000
|
large = size > 200_000
|
||||||
if large:
|
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"
|
fetch_cmd = "BODY.PEEK[]" if large else "RFC822"
|
||||||
_, msg_data = conn.uid("FETCH", uid, fetch_cmd)
|
_, msg_data = conn.uid("FETCH", uid, fetch_cmd)
|
||||||
if msg_data[0] is None:
|
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,
|
emails.append(Email(uid=uid, subject=subject, sender=sender, recipient=recipient,
|
||||||
body=body, date=date_str, reply_to=reply_to, account_email=account.username))
|
body=body, date=date_str, reply_to=reply_to, account_email=account.username))
|
||||||
except Exception as e:
|
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
|
continue
|
||||||
|
|
||||||
conn.logout()
|
try:
|
||||||
|
conn.logout()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
logger.info("共获取 %d 封新邮件", len(emails))
|
logger.info("共获取 %d 封新邮件", len(emails))
|
||||||
return emails
|
return emails
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user