You mentioned "I seldom have more than a couple of lines of code in a
try
always
No, that is not the standard. I, for example, will put all of the code in a
method inside a try/catch block, and then put additional try/catch blocks
and conditional code inside that outer block to catch specific errors. The
outside one is for anything I might have missed. How you use it is up to
you, and what your needs are.
I would never go so far as to put all of the code inside of a method inside
of a try-catch block, because then you are never really sure what you are
catching. Sure, you could simply catch a System.Exception, but if you don't
know what you're catching, and as a result can't react appropriately, you
probably don't want to just sit on that error instead of passing it up
through the call stack.
With VB6, you just had to universally set up an onerror statement that
caught all errors, and then go through and figure out what happened and what
to do about it. The beauty of try-catch is that you can wrap specific
statements and handle it appropriately.
Let's do an example - open up a SQL Server connection, set up a command
object, and execute that command object:
----
SqlConnection connMyConnection = new SqlConnection(szConnectionString);
SqlCommand cmdMyCommand = new SqlCommand("MyCommand", connMyConnection);
cmdMyCommand .CommandType = CommandType.StoredProcedure;
cmdMyCommand .Parameters.Add("@myParameter", SqlDbType.VarChar, 50).Value =
szValue;
connMyConnection.Open();
cmdMyCommand.ExecuteNonQuery();
----
The SqlConnection constructor that I used does not throw an exception, so
there is nothing to catch there.
The SqlCommand constructor that I used does not throw an exception, so there
is nothing to catch there.
Setting the command type could throw an ArgumentException, so you'll want to
catch that.
The add method of the parameters collection doesn't throw an exception, nor
does the Value property of the SqlParameter object, so there is nothing to
catch there.
The Open method of SqlConnection could throw either an
InvalidOperationException or a SqlException, so you'll want to catch that.
The ExecuteNonQuery method of SqlCommand could throw a SqlException, so
you'll want to catch that.
So, you end up with:
----
SqlConnection connMyConnection = new SqlConnection(connectionString);
SqlCommand cmdMyCommand = new SqlCommand("MyCommand", connMyConnection);
try {
cmdMyCommand .CommandType = CommandType.StoredProcedure;
} catch (ArgumentException myArgumentException) {
// do something to react to this - since it's hard coded, you can
probably fix your code and get rid of this check
} finally {
// do some cleanup work
}
cmdMyCommand .Parameters.Add("@myParameter", SqlDbType.VarChar, 50).Value =
szValue;
try {
connMyConnection.Open();
} catch (InvalidOperationException myInvalidOperationException) {
// do something to react to this - since it's hard coded, again you can
probably fix your code and dispense with this check
} catch (SqlException mySqlException1) {
// do something to react to this - either dump to the event log or, if
in debug mode (use preprocessors) write back the message
} finally {
// do some cleanup work
}
try {
cmdMyCommand.ExecuteNonQuery();
} catch (SqlException mySqlException2) {
// do something to react to this - either dump to the event log or, if
in debug mode (use preprocessors) write back the message
} finally {
// do some cleanup work
}
----
If you look up the best practices, you will find it stated in as many words:
"Use try/finally blocks around code that can potentially generate an
exception and centralize your catch statements in one location. In this way,
the try statement generates the exception, the finally statement closes or
deallocates resources, and the catch statement handles the exception from a
central location."
Full list of best practices here:
http://msdn.microsoft.com/library/d...l/cpconbestpracticesforhandlingexceptions.asp
So yes, I would beg to differ. I do consider this a standard. It's what I've
been doing in C++ for years now.
Also, you can check for exceptions before they are thrown. If you are going
to close the aforementioned SqlConnection, instead of just using:
connMyConnection.Close();
use:
if (connMyConnection != null && connMyConnection.State !=
ConnectionState.Closed) {
connMyConnection.Close();
}
And so it goes.
--
Chris Jackson
Software Engineer
Microsoft MVP - Windows XP
Windows XP Associate Expert
--