> Why in the world would you want to set up a global exception handler?
You should catch exceptions relating to what failed...
Absolutely not. You should catch exceptions that you know how to deal
with in your local code. For example, if you're trying to convert a
string to a double, and you know it might fail, but you have a default
value, you should catch the exception, set the default value, and allow
execution to continue.
Another example: if you try to call a Web Service and the call fails,
and that particular call isn't critical to your application, you could
catch the exception, warn the user that some information is not
available, and continue execution.
Global event handlers are for all of those other exceptions: the ones
that you can't handle gracefully... the ones that will kill your
application. A global event handler at least lets you tell the user
nicely that something has gone horribly wrong and you have to shut down
now. For example, we use them to display what we want the user to see
(in a MessageBox) but log the gory details to a log file for analysis
by the IS department.
Again, these are exceptions for which the application has no recovery
strategy, and so has to shut down. You should allow them to go
unhandled, and catch them in the global exception handler in order to
do user-friendly things in such a failure situation.
try
{
///myunknown routine here
}
catch (Exception ex)
{
Messagebox.Show(ex.message);
}
This is wrong on two counts. First and most aggrevious, it shows an
exception message to the user (is that going to mean anything to the
user?) and then _merrily carries on_ executing the program, even
thought the "myunknownroutine" _failed_ with an exception! How do you
know that the application _can_ continue functioning if that routine
fails? Is the state of the application such that it can survive that?
Or is everything in an indeterminate state now, a state that will
result in (at best) further exceptions or (at worst) subtle corruption
of your company's database?
The only way you should ever do this is if you _know_ that
"myunknownroutine" really isn't all that important, and if it fails
it's no big deal. In that case, yes, you should catch the exception,
and either silently log it to a file somewhere, or log it to a file and
warn the user that things are less than optimal, but the program can
still keep working.
The second reason that this is wrong is that you should avoid
catch-alls like "catch (Exception ex)". Carrying on with the idea that
you should only catch exceptions that you know are no big deal, do you
really know that _every exception_ that "myunknownroutine" could
possibly throw is no big deal? What about OutOfMemoryException? Do you
really want to catch that one and continue as though nothing happened?
What about InvalidArgumentException, which indicates an error in your
calling code? What if you verify that every exception is, in fact, no
big deal, but then the next revision of the library adds a new
exception? In general, you should catch _specific exceptions_ that you
know you can deal with, and let the other ones go.
There is one situation I've found, though, in which "catch (Exception
ex)" is inevitable. That's when a vendor's documentation about what
exceptions a method throws is lacking. (See the MSDN documentation on
the Crystal .NET stuff for an example of crap doc that doesn't tell you
_anything_ about exceptions.) In cases like this, you really have no
idea which exceptions a method will throw, so you either have to run
some tests and figure out which exceptions you can handle, or decide
that it's no big deal if the method fails and just do "catch (Exception
ex)". I, for example, use this catch-all and just inform the user that
the report couldn't be printed, and then move on. That's one case in
which a method failure is not a problem.
Global exception handlers are not "old-school programming": they are
the recommended way of gracefully shutting down an application that has
failed.