-
-
Notifications
You must be signed in to change notification settings - Fork 818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sending to multiple recipients via SmtpClient fails entirely if any of the RCPT commands result in errors. #309
Comments
As of, I think, MailKit 1.2.20, I added a Unfortunately, this method is not 100% reliable because some servers always return "command not implemented" (such as comcast) and some always return a status code saying that they don't know if it exists, but that they will attempt delivery (such as gmail). Typically when a server returns "will attempt delivery", it means they'll accept the address in a So depending on your SMTP server, this may or not not be useful for your purpose - I do think it's worth looking into, though, because it'll be a lot more efficient than calling My intended work-around for this problem was to simply catch SmtpCommandExceptions and remove the recipient addresses as they were found to be unavailable/etc. Of course, when doing this, I would recommend using the |
If you'd like to go the route of overriding |
would it be helpful to pass the |
Thank you very much for your reply. I'll give this some thought and, if I find a good solution, I'll add some comments here. |
@NathanLBCooper, in the referenced issue (#256), @jstedfast provided the ability to override Just imagining here -- I might be mistaken/ignorant, so bear with me -- if (and only if) the emails you're sending do not contain private user data, perhaps the ideal solution would be to use a single dedicated, internal address for |
I can't remember... but does MailKit send |
It sends a |
Interesting. Is it considered bad form (or using RFC verbage, "clients SHOULD NOT") to have addresses in the MimeMessage that weren't sent as |
It's not really bad form, in fact it's how clients can send blind carbon copies (the message you send has the Bcc header removed). To be honest, I think the |
So if a recipient isn't added to the SMTP envelope, they won't receive the message regardless of the MimeMessage contents... Oh well, in that case my idea is (partly) bunk :-) |
@jstedfast Is the @NathanLBCooper I suggest overriding |
On second thought, it would be really nice if:
That may not be possible, just my $0.02 based on what I know. |
The The Thinking about this more, I think more than just the |
FWIW, while technically neither of you guys probably need the Also I think it might be something developers could find useful in the sense that if, for example, a |
Agreed, that's a useful piece of data. What do you think about collecting errored |
After thinking about this for a while, I've found a solution that I think will work for everyone. I've dropped
Here's now I envision @NathanLBCooper could implement what he needs: public class MySmtpClient : SmtpClient
{
readonly List<SmtpCommandException> exceptions = new List<SmtpCommandException> ();
protected override void OnSenderAccepted (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
{
exceptions.Clear ();
}
protected override void OnRecipientNotAccepted (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
{
try {
base.OnRecipientNotAccepted (message, mailbox, response);
} catch (SmtpCommandException ex) {
exceptions.Add (ex);
}
}
protected override void OnNoRecipientsAccepted (MimeMessage message)
{
if (exceptions.Count == 1)
throw exceptions[0];
throw new AggregateException (exceptions.ToArray ());
}
} |
FWIW, these changes are included in the MailKit 1.2.21 release that I just published to nuget.org |
Thanks @jstedfast. |
@jstedfast, this is really nice. Previously, I had to copy/paste the |
Excellent :-) |
Thanks @jstedfast. As Tim says, this is a really clean solution. |
Let's say I use SmtpClient to deliver mail to two addresses
disabled@foo.com
andvalid@foo.com
. The first address causes the downstream server to return aSmtpStatusCode.MailboxUnavailable
and the second address is just fine (SmtpStatusCode.Ok
).The method
ProcessRcptToResponse
will throw and noone will recieve any email. As the caller I will be able to see the exception (SmtpCommandException (SmtpErrorCode.RecipientNotAccepted, response.StatusCode, mailbox, response.Response)
) and I'll be able to infer that a email todisabled@foo.com
won't work.My objectives are: 1) to send the message to whoever I can. 2) To know who I can't send messages to (so I can make bounce messages etc).
I notice that your implementation decision was to ditch the whole SMTP conversation if one
RcptTo
fails. Do you recommend any approach or pattern for callers who want to make a best effort attempt to send the email to as many recipients as possible?I've thought about the approach of subclassing and overriding
ProcessRcptToResponse
to raise events and supress exceptions, but in in the event of everything failing continuing on to theBdat
andData
isn't correct. I can't see a non-hacky way to get this control flow right.I have also considered, outside the
SmtpClient
, stripping the recipients out, in turn, as they fail. But that doesn't seem like a good solution either,The text was updated successfully, but these errors were encountered: