Hi Martin,
The (very) short answer: Try...Catch should be used wherever you expect an
exception and you either *know* how to handle that exception or you *need*
to handle that exception.
The (very) long answer:
It's first worth discussing here a subtle distinction in terminology.
Exceptions and errors aren't synonymous; in other words, they're different
creatures. Exceptions can be used to signal errors (such as division by
zero), unexpected events (for instance, the printer running out of paper),
and violations of an interface's assumptions (for example, passing a
parameter with a negative value when the interface expects a positive
value). Although each of these three exceptions could be called an error
from the point of view of the method that throws the exception, it's the
developer writing the code calling the method who really knows what he or
she expects and who therefore defines which of these exceptions is actually
an error from the point of view of the application as a whole.
For example, a method that performs a printing task might throw an exception
because the printer is out of paper, but if the code that calls that method
has been programmed correctly, this would be an expected event, not an error
at all. The exception would just be passed up the call stack before being
transformed into a message asking the user to place some more paper in the
printer.
This distinction is important because when you design a method or class, you
need to decide how you're going to communicate information to the calling
method and which exceptions you're going to throw. Say that you've been
given the task of designing and implementing a class that validates a user
login to an application. In the method that validates the user login, should
an exception be thrown when the login fails or should the method return a
value of false instead?
There is no correct answer to this question. Some developers maintain that a
login failure is an error and therefore an exception should be thrown. Other
developers reason that a login failure is an expected event and not really
an error as far as the application is concerned, therefore the method should
return a status variable rather than forcing the calling code to handle an
exception. Although in this situation I favour returning a status variable
and not throwing an exception, you and your team will have to decide for
yourselves how you are going to handle these design decisions.
One point to bear in mind when making these types of decisions is that you,
as a designer of a method or class, often don't know what the code that
calls your method considers to be an error. If, for instance, you're
developing a method that reads information from a file on disk, how should
you signal that the calling method has read past the end of the file? Is
reading past the end of the file an error or not? Because you don't know
what the calling code is doing, you just don't know whether this is an
error. In this situation, I would throw an exception because I just can't
tell whether the calling code expected to read past the end of the disk
file. Another developer might maintain that reading past the end of a file
is always a possible occurrence as far as most calling code is concerned,
and therefore he would design the method to return a EOF status flag rather
than throw an exception.
Try...Catch should also be used for the following three situations:
1) You want to throw a custom exception rather than the exception that was
thrown. For instance, you might want to signal an error or unexpected event
that isn't described adequately by an existing exception. Or you don't want
to confuse the developer calling your component with an exception thrown by
a component below yours. Finally, you might want to wrap an existing
exception to provide extra information.
2) You want to execute some recovery code. For example, you need to reverse
a transaction that failed before it completed. This strategy can involve
swallowing the original exception or rethrowing it, depending on circumstanc
es.
3) You want to execute some cleanup code. For instance, you need to clean up
after an exception by closing a file or database connection. Once again, you
might want to swallow the original exception or rethrow it, depending on
circumstances.
Apart from these situations, you should let exceptions bubble upwards until
they reach your user interface (if you have one) or your unhandled
(last-chance) exception handler. If it reaches your user interface, you
should catch the exception and display a helpful context-sensitive message
to the end-user. If it reaches your unhandled exception handler, you should
catch the exception and log it somewhere.
HTH,
Mark
--
Author of "Comprehensive VB .NET Debugging"
http://www.apress.com/book/bookDisplay.html?bID=128
Which is best approach?
Should Try + Catch be used to only deal with "catastrophic" events (like
divide by zero, non-existant file, etc...etc...)
Or should Try + Catch be used IN PLACE of regular defensive programming? (ie
if file exists do this, if not do something else)
Or should Try + Catch be used TO SUPPLAMENT regular defensive programming?
What is best "practices" in relation to Try + Catch VS Defensive Programming
in general?