Questo è il modo appropriato per gestire le eccezioni!
In generale, un'eccezione non devono essere manipolati meno che il problema può essere risolto, e dovrebbe essere trattate solo in un luogo in cui può essere applicata la correzione.
Per esempio, il chiamante del codice potrebbe desiderare di richiedere all'utente di correggere l'indirizzo e-mail male. Ma il tuo codice non può sapere il modo giusto per richiedere. Vieni chiamato da WinForms o Web Form? Come dovrebbe apparire la finestra di dialogo? Dovrebbe anche essere una finestra di dialogo? Queste sono cose che possono essere conosciute solo dal chiamante del tuo metodo, e non dal tuo stesso metodo.
Nella chiamante:
try
{
SendEmail(SenderEmail, SenderDisplayName, RecipientEmails, Subject, Message);
}
catch (MyMailAddressException ex)
{
MessageBox.Show(ex.Message);
}
Si noti che tutte le eccezioni diverse da MyMailAddressException
si propagheranno al codice che sa come gestirli.
adeguato livello di "trattamento" nel metodo:
public enum MailAddressType
{
Sender,
Recipient
}
public class MyMailAddressException : Exception
{
public MailAddressType AddressType { get; set; }
public string EmailAddress { get; set; }
public MyMailAddressException(
string message,
MailAddressType addressType,
string emailAddress,
Exception innerException) : base(message, innerException)
{
AddressType = addressType;
EmailAddress = emailAddress;
}
}
public void SendEmail(
string senderEmail,
string senderDisplayName,
IEnumerable<string> recipientEmails,
string subject,
string message)
{
using (
var mailMessage = new MailMessage
{
Subject = subject,
Body = message
})
{
try
{
mailMessage.From = new MailAddress(
senderEmail, senderDisplayName);
}
catch (FormatException ex)
{
throw new MyMailAddressException(
"Invalid from address", MailAddressType.Sender,
senderEmail, ex);
}
foreach (var recipient in recipientEmails)
{
try
{
mailMessage.To.Add(recipient);
}
catch (FormatException ex)
{
throw new MyMailAddressException(
"Invalid to address", MailAddressType.Recipient,
recipient, ex);
}
}
var smtpClient = new SmtpClient("192.168.168.182");
smtpClient.Send(mailMessage);
}
}
Il chiamante può quindi catturare MyMailAddressException
ed avere tutte le informazioni necessarie per dire all'utente cosa sistemare. Altre eccezioni dovrebbero propagarsi.
Le mie precedenti modifiche hanno indirizzato la domanda sul metodo. Presumo che la tua applicazione abbia una gestione delle eccezioni di alto livello appropriata. Gabriel mi fa notare che se avessi una gestione delle eccezioni di primo livello appropriata, la tua applicazione non andrebbe in crash!
Tuttavia, crash non è necessariamente una cosa negativa. Se succede qualcosa che il tuo codice non può gestire, allora l'arresto anomalo è la cosa giusta da fare. L'alternativa è provare a continuare a correre, sperando che questa eccezione non gestita non abbia danneggiato il tuo programma in modo tale che inizi a produrre risultati errati.
Le specifiche di esattamente dove mettere "i gestori di alto livello" dipende dal vostro programma. Ad esempio, è diverso tra WinForms e le applicazioni ASP.NET. Tuttavia, il concetto sarà lo stesso: registrare in sicurezza tutte le informazioni disponibili, quindi consentire l'propagazione dell'eccezione, causando il blocco dell'applicazione.
Ovviamente, è necessario utilizzare i blocchi finally
per pulire l'applicazione, anche in presenza di eccezioni.
No, non lo sto ignorando. Hai visto dove parlo chiedendo all'utente di correggere l'indirizzo email errato? Gestisce l'eccezione. –
No, poiché questo è un metodo di utilità di livello inferiore, le eccezioni dovrebbero assolutamente essere _non_ qui gestite. Lascia fare ai chiamanti. –
@Jon: No, il suo paragrafo intermedio riassume perfettamente il modo in cui le eccezioni erano destinate a essere utilizzate: se il problema può essere risolto. –