C# – Best Practice for Exception Handling in a Windows Forms Application

c++exception-handlingwinforms

I'm currently in the process of writing my first Windows Forms application. I've read a few C# books now so I've got a relatively good understanding of what language features C# has to deal with exceptions. They're all quite theoretical however so what I haven't got yet is a feel for how to translate the basic concepts into a good exception-handling model in my application.

Would anyone like to share any pearls of wisdom on the subject? Post any common mistakes you've seen newbies like myself make, and any general advice on handling exceptions in a way that will my application more stable and robust.

The main things I'm currently trying to work out are:

  • When should I re-throw an exception?
  • Should I try to have a central error-handling mechanism of some kind?
  • Do handling exceptions which might be thrown have a performance hit compared with pre-emptively testing things like whether a file on disk exists?
  • Should all executable code be enclosed in try-catch-finally blocks?
  • Are there any times when an empty catch block might be acceptable?

All advice gratefully received!

Best Solution

A few more bits ...

You absolutely should have a centralized exception handling policy in place. This can be as simple as wrapping Main() in a try/catch, failing fast with a graceful error message to the user. This is the "last resort" exception handler.

Preemptive checks are always correct if feasible, but not always perfect. For example, between the code where you check for a file's existence and the next line where you open it, the file could have been deleted or some other issue may impede your access. You still need try/catch/finally in that world. Use both the preemptive check and the try/catch/finally as appropriate.

Never "swallow" an exception, except in the most well-documented cases when you are absolutely, positively sure that the exception being thrown is livable. This will almost never be the case. (And if it is, make sure you're swallowing only the specific exception class -- don't ever swallow System.Exception.)

When building libraries (used by your app), do not swallow exceptions, and do not be afraid to let the exceptions bubble up. Do not re-throw unless you have something useful to add. Do not ever (in C#) do this:

throw ex;

As you will erase the call stack. If you must re-throw (which is occasionally necessary, such as when using the Exception Handling Block of Enterprise Library), use the following:

throw;

At the end of the day, the very vast majority of exceptions thrown by a running application should be exposed somewhere. They should not be exposed to end users (as they often contain proprietary or otherwise valuable data), but rather usually logged, with administrators notified of the exception. The user can be presented with a generic dialog box, maybe with a reference number, to keep things simple.

Exception handling in .NET is more art than science. Everyone will have their favorites to share here. These are just a few of the tips I've picked up using .NET since day 1, techniques which have saved my bacon on more than one occasion. Your mileage may vary.