mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 01:54:10 +00:00
Every sender turned every failure into `false`, so a one-minute Gmail rate limit or a short outage lost the send like a refused recipient. The three senders now classify through MailDeliveryInterface::deliver(): deferred (rate limits, 5xx, a connection that never opened, SMTP 4xx), refused (other 4xx, SMTP 5xx, too large) or outcome unknown (a lost answer, 502/504). send() stays a bool for invitations, alerts and read receipts. SendMessageHandler retries a deferral for at most two minutes, keeping the provider's Retry-After. A lost answer is never resent blind: Gmail and Graph look for the Message-ID in Sent first (now committed before the first attempt), SMTP reports it as possibly sent. A final failure, from the handler or from SendGaveUpSubscriber when the ladder runs out, marks the draft, words the toast by its reason, and shows a red warning triangle at the start of the draft's row and on Drafts in the sidebar. Migration: four nullable columns and a partial index on message. Closes #125 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>