4

I have a couple of methods already to send an email message syncronously.

If an email fails, I use this fairly standard code:

    static void CheckExceptionAndResend(SmtpFailedRecipientsException ex, SmtpClient client, MailMessage message)
    {
        for (int i = 0; i < ex.InnerExceptions.Length -1; i++)
        {
            var status = ex.InnerExceptions[i].StatusCode;

            if (status == SmtpStatusCode.MailboxBusy ||
                status == SmtpStatusCode.MailboxUnavailable ||
                status == SmtpStatusCode.TransactionFailed)
            {
                System.Threading.Thread.Sleep(3000);
                client.Send(message);
            }
        }
    }

However, I'm trying to achieve the same using SendAsync(). This is the code I have so far:

    public static void SendAsync(this MailMessage message)
    {
        message.ThrowNull("message");

        var client = new SmtpClient();

        // Set the methods that is called once the event ends
        client.SendCompleted += new SendCompletedEventHandler(SendCompletedCallback);

        // Unique identifier for this send operation
        string userState = Guid.NewGuid().ToString();

        client.SendAsync(message, userState);

        // Clean up
        message.Dispose();
    }

    static void SendCompletedCallback(object sender, AsyncCompletedEventArgs e)
    {
        // Get the unique identifier for this operation.
        String token = (string)e.UserState;

        if (e.Error.IsNotNull())
        {
            // Do somtheing
        }
    }

The question is using token and/or e.Error how do I get the exception so that I can make the necessary checks for StatusCode and then resend?

I've been Googling all afternoon but havn't found anything positive.

Any advice appreciated.

dotnetnoob
  • 10,783
  • 20
  • 57
  • 103
  • 1
    Heres a post regarding async exception handling - might allude to whats going on! http://stackoverflow.com/questions/5383310/catch-an-exception-thrown-by-an-async-method – Luke Baughan Feb 28 '13 at 15:14
  • `e.Error` *is* the exception. If that's assigned, something went wrong and you can then investigate the exception properties. – James Feb 28 '13 at 15:17

1 Answers1

4

e.Error already has the Exception that occurred while sending the email async. You can check the Exception.Message, Exception.InnerException, Exception.StackTrace, etc. to get further details.

Update:

Check if the Exception is of type SmtpException and if it is, you can query the StatusCode. Something like

if(e.Exception is SmtpException)
{
   SmtpStatusCode  code = ((SmtpException)(e.Exception)).StatusCode;
   //and go from here...
} 

And check here for further details.

Icarus
  • 63,293
  • 14
  • 100
  • 115
  • Icarus - I can see InnerException how can I then test (the equivalent of StatusCode) and resend the message. Any ideas? – dotnetnoob Feb 28 '13 at 15:46
  • 1
    `if (e.Error is SmtpException)` is correct syntax because there is no `if (e.Exception is SmtpException)`. Thanks for the answer, helpful. – One-One Apr 07 '15 at 07:05