A good start to your solution would be to actually utilize what catch
can do, and what the various Exception
classes provide in feedback.
Your current implementation does nothing for handling. IntelliSense probably has flagged ex
as not being used
catch (Exception ex) {
return false;
}
In the case of an SMTP Exception, you can retrieve the actual status code and look up what the status means. This would go in above your existing generic catch and handler.
catch (SmtpException sx) { // general SMTP errors
var smtpStatus = sx.StatusCode;
// See for values: https://msdn.microsoft.com/en-us/library/system.net.mail.smtpstatuscode(v=vs.110).aspx
LogSmtpException(sx); // Log your exception review (you need to create)
return false;
}
catch (Exception ex) { // general error NOT previously caught
LogException(ex); // Log your exception review (you need to create)
return false;
}
But there is an even more specific SMTP Exception you could get, usually for a bad address, so we could throw that on top of the 2 other catches
catch (SmtpFailedRecipientException rx) { // Bad recipient
var smtpStatus = rx.StatusCode; // inherited from SmtpException
// SEE: https://msdn.microsoft.com/en-us/library/system.net.mail.smtpfailedrecipientexception(v=vs.110).aspx
LogSmtpException(sx); // Log your exception review (same as SmtpException)
return false;
}
catch (SmtpException sx) { // general SMTP errors
var smtpStatus = sx.StatusCode;
LogSmtpException(sx);
return false;
}
catch (Exception ex) { // general error NOT previously caught
LogException(ex);
return false;
}
What I have implemented
My "Send Mail" routine is not a bool method; it actually returns a KeyValuePair<int, string>
, which is interpreted by the caller.
KeyValuePair<int, string> MessageStatus = new SendMail(my values);
if ((int)MessageStatus.Key == 250) {
// all ok, proceed as normal
}
else {
ViewData["StatusCode"] = MessageStatus.Key;
ViewData["StatusMessage"] = MessageStatus.Value;
}
And my SendMail is structured like this. I do not lookup the exact reason at the time of the event, but I log the exceptions for later review.
public KeyValuePair<int, string> SendMail (my values) {
int StatusCode;
string StatusMessage;
// ===== standard message building code =====
try {
// ===== smtp client setup code =====
smtp.Send(mail);
StatusCode = 250; // Standard SMTP OK
StatusMessage = "Message Sent";
}
catch (SmtpFailedRecipientException rx) {
LogExceptionSMTP(rx, message.To);
StatusCode = (int)rx.StatusCode;
StatusMessage = rx.Message;
}
catch (SmtpException sx) {
LogExceptionSMTP(sx, message.To);
StatusCode = (int)sx.StatusCode;
StatusMessage = sx.Message;
}
catch (Exception ex) {
ex.Data.Add( "SendMail_Recipient", message.To );
LogException(ex);
StatusCode = 500; // Standard App Error Code
StatusMessage = ex.Message;
}