{"action":"created","issue":{"url":"https://api.github.com/repos/jstedfast/MailKit/issues/309","repository_url":"https://api.github.com/repos/jstedfast/MailKit","labels_url":"https://api.github.com/repos/jstedfast/MailKit/issues/309/labels{/name}","comments_url":"https://api.github.com/repos/jstedfast/MailKit/issues/309/comments","events_url":"https://api.github.com/repos/jstedfast/MailKit/issues/309/events","html_url":"https://github.com/jstedfast/MailKit/issues/309","id":139886026,"number":309,"title":"Sending to multiple recipients via SmtpClient fails entirely if any of the RCPT commands result in errors.","user":{"login":"NathanLBCooper","id":10466530,"avatar_url":"https://avatars.githubusercontent.com/u/10466530?v=3","gravatar_id":"","url":"https://api.github.com/users/NathanLBCooper","html_url":"https://github.com/NathanLBCooper","followers_url":"https://api.github.com/users/NathanLBCooper/followers","following_url":"https://api.github.com/users/NathanLBCooper/following{/other_user}","gists_url":"https://api.github.com/users/NathanLBCooper/gists{/gist_id}","starred_url":"https://api.github.com/users/NathanLBCooper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NathanLBCooper/subscriptions","organizations_url":"https://api.github.com/users/NathanLBCooper/orgs","repos_url":"https://api.github.com/users/NathanLBCooper/repos","events_url":"https://api.github.com/users/NathanLBCooper/events{/privacy}","received_events_url":"https://api.github.com/users/NathanLBCooper/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-03-10T13:30:00Z","updated_at":"2016-03-10T14:15:02Z","closed_at":null,"body":"Let's say I use [SmtpClient](https://github.com/jstedfast/MailKit/blob/16cf225a4e194d0153d7f024b073e05f7cd7f639/MailKit/Net/Smtp/SmtpClient.cs) to deliver mail to two addresses `disabled@foo.com` and `valid@foo.com`. The first address causes the downstream server to return a `SmtpStatusCode.MailboxUnavailable` and the second address is just fine (`SmtpStatusCode.Ok`).\r\n\r\nThe 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 to `disabled@foo.com` won't work.\r\n\r\nMy 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).\r\n\r\nI 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?**\r\n\r\nI'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 the `Bdat` and `Data` isn't correct. I can't see a non-hacky way to get this control flow right.\r\n\r\nI 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,"},"comment":{"url":"https://api.github.com/repos/jstedfast/MailKit/issues/comments/194864540","html_url":"https://github.com/jstedfast/MailKit/issues/309#issuecomment-194864540","issue_url":"https://api.github.com/repos/jstedfast/MailKit/issues/309","id":194864540,"user":{"login":"jstedfast","id":338984,"avatar_url":"https://avatars.githubusercontent.com/u/338984?v=3","gravatar_id":"","url":"https://api.github.com/users/jstedfast","html_url":"https://github.com/jstedfast","followers_url":"https://api.github.com/users/jstedfast/followers","following_url":"https://api.github.com/users/jstedfast/following{/other_user}","gists_url":"https://api.github.com/users/jstedfast/gists{/gist_id}","starred_url":"https://api.github.com/users/jstedfast/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jstedfast/subscriptions","organizations_url":"https://api.github.com/users/jstedfast/orgs","repos_url":"https://api.github.com/users/jstedfast/repos","events_url":"https://api.github.com/users/jstedfast/events{/privacy}","received_events_url":"https://api.github.com/users/jstedfast/received_events","type":"User","site_admin":false},"created_at":"2016-03-10T14:15:02Z","updated_at":"2016-03-10T14:15:02Z","body":"As of, I think, MailKit 1.2.20, I added a `Verify(MailboxAddress)` method to SmtpClient that can be used to check whether or not the SMTP server will accept an email address.\r\n\r\nUnfortunately, 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 `RCPT TO` command just fine.\r\n\r\nSo 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 `Send()` and having it fail and then removing addresses until it finally goes through.\r\n\r\nMy intended work-around for this problem was to simply catch SmtpCommandExceptions and remove the recipient addresses as they were found to be unavailable/etc.\r\n\r\nOf course, when doing this, I would recommend using the `Send()` method that takes an explicit sender and list of recipients as opposed to just the `MimeMessage` so that you don't actually have to modify the message itself on fail, but I suppose that all depends on your use case."}}