Skip to content

Expose per-recipient SMTP replies and retry guidance #723

Closed

Description

@bbottema

Part of #722, phase 1 of 03_SMTP_ROBUSTNESS_IMPROVEMENT_PLAN. Extends the unreleased submission-result API from #710.

Why

A failed send does not necessarily mean that no mail was accepted. Mixed recipients can receive different SMTP replies, and losing the final DATA reply leaves acceptance uncertain. Applications need those facts to decide whether to retry the whole message, retry particular recipients, or ask for human review.

Angus also deliberately throws reporting exceptions when mail.smtp.reportsuccess=true, even after complete acceptance. Simple Java Mail currently misclassifies that successful transaction; this phase corrects it.

Scope

  • Add immutable recipient results in envelope order, with original/mailbox addresses, final submission disposition, RCPT-attempt knowledge, the observed primary reply and text, and an optional enhanced status.
  • Retain existing accepted, valid-unsent and invalid recipient getters as immutable compatibility views.
  • Derive conservative transaction-level retry guidance and a known-retryable recipient list. Never resend automatically or imply exactly-once delivery.
  • Extract provider exception types structurally; normalize genuine success-reporting exceptions only when the whole transaction was accepted.
  • Keep original provider failures, missing replies, unknown final acceptance, custom mailers and third-party adapters intact.
  • Keep captured facts local to one attempt, including pooled async sends, simple batches, open connections and observers.

Acceptance

  • All-success reporting mode returns success.
  • Mixed 2xx/4xx/5xx RCPT results, final rejection and final-reply loss remain distinct.
  • Enhanced-status parsing rejects malformed or conflicting status text.
  • Ordered recipient results agree with compatibility views and remain immutable.
  • Retry guidance excludes permanent rejection and flags duplicate risk.
  • Actual pooled SMTP tests cover concurrency, reuse, invalidation and recovery.
  • Classpath/JPMS consumers and incomplete third-party provider results remain supported.
  • Existing submission-result documentation explains the API and its limits.

Phase 1 is complete and accepted. The implementation was committed as f79c66c6 and is already on the pushed codex/10.0.0 branch, with documentation included. Closing this leftover tracking item does not introduce new Phase 1 work. The changes remain unreleased until 10.0.0 ships; later steps are tracked under #722.

Activity

  1. added this to the 10.0.0 milestone on Sep 7, 2026
  2. self-assigned this
    on Sep 7, 2026
  3. moved this from Todo to In Progress in Simple Java Mail 10.0.0on Sep 7, 2026
  4. bbottema commented on Sep 17, 2026

    @bbottema
    OwnerAuthor

    This was already accepted and pushed for 10.0.0; closing the leftover tracking issue.

    Use receipt.getRecipientResults() for each recipient's observed reply and disposition, and receipt.getRetryDisposition() / getRetryableRecipients() for conservative retry guidance. A missing final DATA reply remains uncertain and can mean duplicate risk; no automatic retry is performed.

    Usage and sample output. The remaining roadmap stays under #722.

  5. moved this from In Progress to Done in Simple Java Mail 10.0.0on Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions