Search code examples
c#.netemailsmtp

Capture SMTP errors in .NET


Normally, I'd send emails like that:

int statusCode = 0;
string error = null;

try
{
    smtp.Send(mailMessage);
    statusCode = 250;
}
catch (SmtpFailedRecipientException e)
{
    Log(String.Format("[Exception] {0}\n\tSmtp: {1}{2}:{3}\n\tStatus Code: {4}\n\tFaild Recipient: {5}", e.Message, smtp.Key, smtp.Value.Host, smtp.Value.Port, e.StatusCode, e.FailedRecipient));

    statusCode = (int)e.StatusCode;
    error = e.Message;
}
catch (SmtpException e)
{
    Log(String.Format("[Exception] {0}\n\tSmtp: {1} - {2}:{3}\n\tStatus Code: {4}", e.Message, smtp.Key, smtp.Value.Host, smtp.Value.Port, e.StatusCode));

    statusCode = (int)e.StatusCode;
    error = e.Message;
}
catch (Exception e)
{
    Log(String.Format("[Exception] {0}.\n\tSource: {1}\n\tStack Trace: {2}", e.Message, e.Source, e.StackTrace));

    statusCode = -1;
    error = "General Failure";
}

But this method doesn't allow me to catch some of the more "advanced" SMTP errors such as No Domain, No such Email, etc.

How can I capture that kind of SMTP errors? Is that even possible?

For example, when I'm trying to send in Gmail to an address such as asdfkljhadf@dgdfasdf.com, Gmail sends me after a while an Email that asdfkljhadf@dgdfasdf.com doesn't exist.


Solution

  • SMTP is a "store and forward" protocol, meaning that the server can accept a message for forwarding, but not know at the time that the message can't be delivered. So, for example, when you tell your ISP's SMTP server to deliver a message to "invalidaddress@example.com", the server's response is, "Okay, I'll forward it." At some later time, the ISP's SMTP server will contact the SMTP server for "example.com", and try to deliver the message. Only then does it know that the mail is undeliverable.

    So as far as the communication between your client and the SMTP server is concerned, the message was delivered successfully--the server agreed to forward it. Therefore, no exception.