Casi nunca debe usar try/catch.
Solo debe hacer catch
excepciones que puede corregir, y solo cuando las está esperando. De lo contrario, permita que la persona que llama maneje la excepción, o no.
Si se usa, cualquier cláusula catch
se ejecuta primero, solo una de ellas.
Luego, se ejecuta "finalmente" finally
.
Esto se ha expresado mejor en muchos lugares, pero lo intentaré. El siguiente código:
try
{
// Do something here
}
catch (Exception ex)
{
MessageBox.Show("Friendly error message");
}
no repara la excepción. Oculta la excepción para que el problema nunca se solucione. Ese código no tiene idea de qué excepción fue lanzada, porque las detectará todas, y no hace nada para corregir el problema, simplemente le dice al usuario una ficción educada.
El quid de la cuestión es que el código anterior debe ser sustituido por el siguiente:
// Do something here
esta manera, si la persona que llama de este método sabe cómo solucionar problemas particulares, entonces la persona que llama puede solucionarlos . No habrá eliminado esa opción de la persona que llama.
Si la persona que llama no sabe cómo solucionar el problema, la persona que llama tampoco debería detectar la excepción.
Aquí hay un ejemplo (de MSDN) sobre el uso razonable de excepciones. Es una forma modificada del ejemplo en la documentación del SmtpFailedRecipientsException Class.
public static void RetryIfBusy(string server)
{
MailAddress from = new MailAddress("[email protected]");
MailAddress to = new MailAddress("[email protected]");
using (
MailMessage message = new MailMessage(from, to)
{
Subject = "Using the SmtpClient class.",
Body =
@"Using this feature, you can send an e-mail message from an application very easily."
})
{
message.CC.Add(new MailAddress("[email protected]"));
using (SmtpClient client = new SmtpClient(server) {Credentials = CredentialCache.DefaultNetworkCredentials})
{
Console.WriteLine("Sending an e-mail message to {0} using the SMTP host {1}.", to.Address, client.Host);
try
{
client.Send(message);
}
catch (SmtpFailedRecipientsException ex)
{
foreach (var t in ex.InnerExceptions)
{
var status = t.StatusCode;
if (status == SmtpStatusCode.MailboxBusy || status == SmtpStatusCode.MailboxUnavailable)
{
Console.WriteLine("Delivery failed - retrying in 5 seconds.");
System.Threading.Thread.Sleep(5000); // Use better retry logic than this!
client.Send(message);
}
else
{
Console.WriteLine("Failed to deliver message to {0}", t.FailedRecipient);
// Do something better to log the exception
}
}
}
catch (SmtpException ex)
{
// Here, if you know what to do about particular SMTP status codes,
// you can look in ex.StatusCode to decide how to handle this exception
// Otherwise, in here, you at least know there was an email problem
}
// Note that no other, less specific exceptions are caught here, since we don't know
// what do do about them
}
}
}
Tenga en cuenta que este código utiliza try/catch para rodear un pequeño fragmento de código. Dentro de ese bloque try/catch, si se lanza una excepción SmtpException o SmtpFailedRecipientsException, sabemos qué hacer al respecto. Si, por ejemplo, tuviéramos que atrapar IOException
, no sabríamos lo que significaba o qué hacer al respecto. Cualquier excepción que no sepas cómo corregir no se debe capturar, excepto tal vez para agregar información a la excepción, registrarla y volver a lanzar.
Por favor, aprender a utilizar puntos finales ('.') y signos de interrogación ('?') apropiadamente. No puedo entender tu pregunta tal como está actualmente. – BoltClock