Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch specific exceptions when sending mail?

I have the following piece of code

try
{
  if (!bDebug)
    smtp.Send(m);
}
catch (Exception e)
{
  wl("Meldingen kunne ikke sendes til en eller flere mottakere.", ConsoleColor.Red);
  wl(e.Message, ConsoleColor.DarkRed);
  using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
  {
    errorfile.WriteLine(e.StackTrace);
    if (e.GetType() == typeof(SmtpFailedRecipientException))
    {
      var se = (SmtpFailedRecipientException) e;
      errorfile.WriteLine(se.FailedRecipient);
    }
    errorfile.WriteLine(e.ToString());
  }
}

Where wl is a shortcut for writing to the console with color, and the text in the first line says "The message could not be sent to one or more recipients.

Previously I only caught the SmtpFailedRecipientException, but when it started failing in some other steps I shoved the generic Exception in there. So the part I'm wondering about is where I'm casting the Exception object into a more specific object to get the FailedRecipient property. Could/should this be done in another more proper way? It seems a bit clunky...

like image 834
Christian Wattengård Avatar asked Dec 12 '22 13:12

Christian Wattengård


2 Answers

You can have multiple catch branches:

catch (SmtpFailedRecipientException se)
{
  using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
  {
    errorfile.WriteLine(se.StackTrace);  
    // variable se is already the right type, so no need to cast it      
    errorfile.WriteLine(se.FailedRecipient);       
    errorfile.WriteLine(se.ToString());
  }
}
catch (Exception e)
{
  wl("Meldingen kunne ikke sendes til en eller flere mottakere.", ConsoleColor.Red);
  wl(e.Message, ConsoleColor.DarkRed);   

  // for other error types just write the info without the FailedRecipient
  using (var errorfile = System.IO.File.CreateText("error-" + DateTime.Now.Ticks + ".txt"))
  {
    errorfile.WriteLine(e.StackTrace);        
    errorfile.WriteLine(e.ToString());
  }

}
like image 135
JK. Avatar answered Dec 27 '22 16:12

JK.


You can try somthing like this(source):

We're going to learn how to catch/handle different types of exceptions/errors that might occur while sending an email using ASP.Net. We'll implement error/exception handling using different exception classes available in System.Net.Mail.

First to learn how to send an email using ASP.Net visit this link. Notice that in the above article (lead by link) the 'SendEmails' catches only a generic exception and in case ASP.Net encounters an error while sending email it would be like 'Sending email failed etc'. We'll extend the error handling functionality for the above article. So lets get started by openning the solution we created previously. We already have put a try-catch block that catches a generic exception that tells very little about what might have gone wrong. Let's catch different types of exception right away:

Catch the SmtpException: The SmtpException class has a property 'StatusCode' which is actually an enumeration that gets the error/exception code value returned by the SMTP server when an email message is transmitted. It also provides more details of error/exception that can occur during the email sending process. e.g.

catch (SmtpException smtpException) 
{ // You can put a switch block to check for different exceptions or errors    

 // To checks if the destination mailbox is busy 
 if (smtpException.StatusCode == SmtpStatusCode.MailboxBusy) 
   throw smtpException; 

 // To check if the client is authenticated or is allowed to send email using the specified SMTP host 
 if (smtpException.StatusCode == SmtpStatusCode.ClientNotPermitted) 
   throw smtpException; 
 // The following code checks if the email message is too large to be stored in destination mailbox 

 if (smtpException.StatusCode == SmtpStatusCode.ExceededStorageAllocation) 
   throw smtpException; 
 // To check if the email was successfully sent to the SMTP service 

 if (smtpException.StatusCode == SmtpStatusCode.Ok) 
   throw smtpException; 
 // When the SMTP host is not found check for the following value 

 if (smtpException.StatusCode == SmtpStatusCode.GeneralFailure) 
   throw smtpException;             
} 

Catch the SmtpFailedRecipientException: The SmtpFailedRecipientException class deals with the exception related to the recipient of the email e.g. SMTP is not able to send the email to a recipient. The SmtpFailedRecipientException occurs when SmtpClient is not able to complete a SmtpClient.Send() or SmtpClient.SendAsync() operation to a particular recipient. To catch this exception use the following code:

catch (System.Net.Mail.SmtpFailedRecipientException smtpFailedRecipientException) 
{ 
 // Get the email that is causing email sending failed exception 
 String emailCausingException = smtpFailedRecipientException.FailedRecipient; 

 // Get the status code why and what is actually causing an email sending error 
 System.Net.Mail.SmtpStatusCode statusCode = smtpFailedRecipientException.StatusCode; 

 // Take some action either re-send the email again or do some error handling code here 
}

Catch the SmtpFailedRecipientsException: The SmtpFailedRecipientsException is actually a collection of SmtpFailedRecipientException objects serving the same purpose. It is used to handle exceptions when SmtpClient is not able to send emails to one or more recipients.

catch (System.Net.Mail.SmtpFailedRecipientsException smtpFailedRecipientsException) 
{ 
 ArrayList emailCausingException = new ArrayList(); 

 foreach (SmtpFailedRecipientException smtpFailedRecipientException 
               in smtpFailedRecipientsException.InnerExceptions) 
{ 
   // Get the email that is causing email sending failed exception 
   // Add it to a list of emails with exceptions 
   emailCausingException.Add(smtpFailedRecipientException.FailedRecipient);

   // Get the status code why and what is actually causing an email sending error 
   System.Net.Mail.SmtpStatusCode statusCode = smtpFailedRecipientException.StatusCode; 
   // Take some action either re-send the email again or do some error handling 
   // You can also log or print this status code for an individual recipient here 
   if (statusCode == SmtpStatusCode.MailboxBusy) 
   { 
     //Re-Send email after some time 
     System.Threading.Thread.Sleep(1000); 
     //smtpClient.Send(); 
     //Email sending code here 
   } 
 } 
}
like image 21
danyolgiax Avatar answered Dec 27 '22 16:12

danyolgiax