email: fix backfill crash on emails with no Reply-To; Sync now retries errored mailboxes (v0.1.0:62)
insert_email's recipients loop did `for a in parsed.get(kind, [])`, but the parser sets reply_to=None when there is no Reply-To header, so .get returns None (key present) and the loop raised 'NoneType' object is not iterable — aborting the entire Gmail backfill on the first such email (i.e. almost immediately). Fixed with `or []`. Regression test test_insert_email.py (reply_to=None, all-None recipients, happy path). Because the scheduler intentionally skips error-status accounts (no retry storms), an errored mailbox would never resume on its own. "Sync now" now clears error status first, so it is an explicit retry; backfill resumes from its saved cursor and dedups by Message-ID, so nothing is re-captured. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -377,6 +377,17 @@ def _h_run_now(handler):
|
||||
# Reuse existing rate limit so admins can't hammer this.
|
||||
if handler.rate_limited("email-sync-now", 6):
|
||||
return handler.send_error_json("Too many requests", 429)
|
||||
# A manual sync is an explicit retry. The scheduler intentionally skips
|
||||
# error-status accounts (no retry storms), so clear that status here so a
|
||||
# mailbox that previously errored is re-attempted. Backfill resumes from its
|
||||
# saved cursor and dedups by Message-ID, so nothing is re-captured twice.
|
||||
conn = _conn()
|
||||
try:
|
||||
conn.execute("UPDATE email_accounts SET sync_status = 'pending', sync_error = NULL "
|
||||
"WHERE sync_enabled = 1 AND sync_status = 'error'")
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
result = _sched.trigger_run_now()
|
||||
handler.send_json(result)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user