You should almost never use try / catch.
You should only use catch tags that you can fix, and only when you expect them. Otherwise, let the caller handle the exception - or not.
If used, any catch are executed first - only one of them.
Then finally is executed.
It has been said better in many places, but I will try. The following code:
try { // Do something here } catch (Exception ex) { MessageBox.Show("Friendly error message"); }
does not correct the exception. It hides the exception, so the problem will never be fixed. This code has no idea which exception was thrown, because it will catch all of them, and it does nothing to fix the problem - it just tells the user polite fiction.
The fact is that the above code should be replaced with the following:
Thus, if the caller of this method knows how to fix certain problems, the caller can fix them. You will not remove this option from the caller.
If the caller does not know how to fix the problem, then the caller should also not catch the exception.
Here is an example (from MSDN) of using exceptions in a reasonable way. This is a modified form of the example in the SmtpFailedRecipientsException Class documentation.
public static void RetryIfBusy(string server) { MailAddress from = new MailAddress(" ben@contoso.com "); MailAddress to = new MailAddress(" jane@contoso.com "); 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(" Notifications@contoso.com ")); 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);
Note that this code uses try / catch to surround a small piece of code. Inside this try / catch block, if a SmtpException or SmtpFailedRecipientsException is thrown, we know what to do with it. If, for example, we were to catch an IOException , we would not know what this means, or what to do about it. Any exception that you do not really know how to fix should not be caught, except, perhaps, to add information to the exception, for registration and retronization.