Exception handling placement - C# - c#

I've decided to remove some of the using statements in my code so I can catch specific exceptions and handle the disposing of resources manually. I have refactored some of the code to make it more readable and maintable, after implementing the new try/catch block I am left wondering if they have been placed correctly for the task at hand.
Example:
public static DataTable Select(string table, string[] column, Object operand)
{
DataTable dTable = null;
SQLiteConnection connection = null;
SQLiteCommand command = null;
SQLiteDataReader dReader = null;
//convert to array for arguments
StringBuilder query = new StringBuilder();
query.Append("select ");
for (int i = 0; i < column.Length; i++)
{
query.Append(column[i]);
if (i < column.Length - 1)
{
query.Append(",");
}
}
query.Append(" from ");
query.Append(table);
try
{
connection = new SQLiteConnection(_connectionString);
command = new SQLiteCommand(query.ToString(), connection);
dTable = new DataTable();
connection.Open();
dReader = command.ExecuteReader();
dTable.Load(dReader);
return dTable;
}
catch (SQLiteException sqle)
{
//Handle exception
}
finally
{
connection.Dispose();
command.Dispose();
dReader.Dispose();
dTable.Dispose();
}
return null;
}
In this example I have only implemented the try/catch around the SQL operations themselves, I did this as it ensures any exceptions that are thrown can be noted and the resourced disposed correctly. I then noticed that this left the for loop open to exceptions, although the supplied indexer will be protected and created via a GUI.
Would I be wise to encapsulate the entire method in the try/catch statement or am I being overly cautious? You could say I'm looking for the best practice when it comes to managing the placement of the statements themselves.
Thanks for your time!
Edit:
I know that the using statement would be ideal in terms of handling the disposal and management of resources however as mentioned at the beginning of the question I wish to be able to catch specific types of exceptions, in particular those generated from the SQLite components.

Don't forget a null check:
finally {
if (connection != null) connection.Dispose();
if (command != null) command.Dispose();
if (dReader != null) dReader.Dispose();
if (dTable != null) dTable.Dispose();
}
It is possible that one of the constructors throws an exception, in that case the objects will not have been initialized.

Why use try/catch explicitly when what you are concerned about is resource management? Use using instead:
using(SQLiteConnection connection = new SQLiteConnection(_connectionString))
{
..
using(SQLiteCommand command = new SQLiteCommand(query.ToString(), connection))
{
using(SQLiteDataReader reader = dReader = command.ExecuteReader())
{
dTable.Load(dReader);
}
}
}
Also currently you are returning dTable, but you are disposing it in your finally block.

You could enclose the entire method in a try/catch if you think that there's any likelihood that exceptions will be thrown outside of the scope of database problems. You can easily differentiate the exceptions by what you catch. For example:
DataTable dTable = null;
SQLiteConnection connection = null;
SQLiteCommand command = null;
SQLiteDataReader dReader = null;
try
{
// non-DB code
// DB code
}
catch (SQLiteException sqle)
{
// Handle DB exception
}
catch (IndexOutOfRangeException ie)
{
// If you think there might be a problem with index range in the loop, for example
}
catch (Exception ex)
{
// If you want to catch any exception that the previous catches don't catch (that is, if you want to handle other exceptions, rather than let them bubble up to the method caller)
}
finally
{
// I recommend doing some null-checking here, otherwise you risk a NullReferenceException. There's nothing quite like throwing an exception from within a finally block for fun debugging.
connection.Dispose();
command.Dispose();
dReader.Dispose();
dTable.Dispose();
}
return null;

A bigger problem you've introduced with this refactoring can be seen when you consider what will happen when the creation of one of the intermediate entities fails. For example, if the connection creation throws, then what happens to the exception thrown in your finally block that attemts to call Dispose on all those null variables? At least check for null beforehand, or put an additional try/catch inside your finally. I'd say you could benefit from the use of Resharper, which would have already pointed out these issues.

I don't know if it is best practice but I usually put try/catch statements around blocks of code where external resources are accessed like database access, file I/O, etc. which might spit out exceptions due to various reason (inaccessible resource, I/O error, etc.). I don't protect code which I'm in control of - that's where unit tests come into place
Btw: You know that you can replace your loop with string.Join()?
Update: Just to clarify: try/catch blocks only really make sense if you want to catch specific exception and execute some custom logic. Otherwise you should stick to using and let the exception bubble up and deal with it at the appropriate place (e.g. notify the user that some data could not be saved because the server is unavailable or so)

If all you are worried about is properly disposing of things, you should be using a 'using' block for this. http://msdn.microsoft.com/en-us/library/yh598w02.aspx

Related

A single method throws same type of exception for different reasons in C#

I have a method UpdateSQL() which may throw exception of same type (SqlException) for two or more different unrelated reasons. Reason 1 = "Invalid connection string" while executing sqlConn.open() . Reason 2 = "Some error while executing Stored Procedure" while executing sqlCommand.ExecuteNonQuery(). How do I identify the reason for which the SqlException was thrown at the caller method so that I could log a custom reason?
Caller Method
try
{
UpdateSQL();
}
catch(SqlException e)
{
// How do i know the reason for which exception was thrown so I could log
log.LogError(e, "Reason");
}
Update method -
UpdateSQL()
{
using (var sqlConn = new SqlConnection("myConnString"))
{
sqlConn.Open(); // May throw exception for reason 1
SqlCommand sqlCommand = new SqlCommand("myStoredProcedure", sqlConn);
sqlCommand.CommandType = CommandType.StoredProcedure;
// Some random parameter
SqlParameter myParam = sqlCommand.Parameters.AddWithValue("#Time", "3/10/2015 2:15:10 AM");
myParam.SqlDbType = SqlDbType.NVarChar;
sqlCommand.ExecuteNonQuery(); // May throw exception for reason 2
}
}
One possible method that I can see is that wrapping the two Sql commands itself in separate try-catch blocks at the Update method. But is there a way to avoid this?
When it comes to logging especially I would avoid doing any custom logic around SqlException and just personally log the Error Message + Error number for lookup. The reason for not doing this is because logging should be relatively simple and you should not write logic you have to further test.
Typically just log something similar to what the docs share. Here is a more condensed version I typically would use in my logs.
Logger.Log(String.Join(Environment.NewLine,
exception.Errors.Select( (error, i) => $"Error [{i}]: {Error.Message} : Error Number {error.Number}" ));
If you need to perform actual business logic there is not really a great way to handle this other than be pretty explicit and use the error numbers to branch to different logic based on error numbers directly or error number ranges. Something like this should get that job done reasonably well.
try
{
// do Sql stuff here
}
catch(SqlException sqlException) when (e.Errors.Select(e => e.Number).Contains(new []{25})
{
// Log Something about bad connection string..
// it happens to be 25 from what I've seen
// which tbh I cant find the docs for :(
}
catch(SqlException sqlException) when (e.Errors.Select(e => e.Number).Contains(new []{1,2,3})
{
// Log Some other kind of Error
}

An exception can lead to the closing of a SqlConnection?

I'm building the treatment of a connection and came this question in mind, but I could not find a satisfactory answer. Then I come here to ask more experienced programmers. Is there any possibility that an exception can lead to the closing of an already opened SqlConnection?
illustrative code:
SqlConnection con = new SqlConnection(connectionString);
con.Open();
try
{
// some code that can throw an exception here....
}
catch (Exception)
{
// is there any possibility of this error close the connection?
}
Is there any possibility of an exception lead to the closing of an
already open SqlConnection?
Exceptions will not voluntarily close an open SqlConnection. In all instances, you have to take care of its resources. You can do this by explicitly calling the Close() method (best in a finally block), or wrapping it in a using statement (this technique is often preferred).
Explicitly calling .Close()
SqlConnection con = new SqlConnection(connectionString);
con.Open();
try
{
//some code that can throw an exception here....
}
catch (Exception)
{
//is there any possibility of this error close the connection? no
}
finally
{
//call close here - finally block will always execute
con.Close();
}
Using statement
using (SqlConnection con = new SqlConnection(connectionString)) {
con.Open();
try
{
//some code that can throw an exception here....
}
catch (Exception)
{
//is there any possibility of this error close the connection? no
}
//Close() is taken care of by the using statement
}
Also, I'd recommend putting your Open() call inside your try-catch as it can throw an exception.
Edit:
In case you're unsure about what the using statement does:
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
You can read more about it in MSDN's documentation

Performance comparison between using block and Dispose method

Think about these 2 snippets:
Approach 1: use using statement
using(var connection = new SqlConnection())
using(var command = new SqlCommand(cmdText, connection)){
try{
connection.Open();
using(var reader = command.ExecuteReader(
CommandBehavior.CloseConnection | CommandBehavior.SingleResult){
while(reader.Read())
// read values
}
} catch (Exception ex) {
// log(ex);
}
}
Approach 2: use try/finally
var connection = new SqlConnection();
var command = new SqlCommand(cmdText, connection);
SqlDataReader = null;
try{
var reader = command.ExecuteReader(
CommandBehavior.CloseConnection | CommandBehavior.SingleResult);
while(reader.Read())
// read values...
} catch (Exception ex) {
// log(ex);
} finally {
command.Dispose();
if (reader != null) {
if (!reader.IsClosed)
reader.Close();
reader.Dispose();
}
if (connection.State != ConnectionState.Closed)
connection.Close();
connection.Dispose();
}
We all know that the using statements would be compiled to try/finally blocks. So is it correct to say: when the app get compiled, there would be 4 try blocks?
try { // for using SqlConnection
try { // for using SqlCommand
try { // my own try block
try { // for using SqlDataReader
} finally {
// dispose SqlDataReader
}
} catch {
// my own catch. can be used for log etc.
}
} finally {
// dispose SqlCommand
}
} finally {
// dispose SqlConnection
}
And, if the answer is yes, wouldn't that be a performance issue? Generally, is there any, I mean any performance difference between using blocks and try/finally blocks?
UPDATE:
From comments, I've to say:
1- The important question is, having multiple try blocks inside each other: is there any performance issue?
2- I have to care of code, because I'm responsible to code, not to query. The query-side has its own developer which is doing his best. So, I have to do my best too. So, it's important to me to take care of milliseconds ;) Thanks in advance.
Usually when you hear about try/catch is slow, it's all about exception handling. So if exception occurs then it might be slow. But just entering in try method is not something you should worry about. Especially in your case when you warp SQL query call.
If you want to know more about exceptions and performance in .NET you can find a lot of articles to read. For example: MSDN article or great CodeProject article.
And of course using is preferable way because it makes code much cleaner.

working with database Best practise?

I have a C# database layer that with static read method that is called every second in background timer.
currently I create SqlCommand, SqlConnection once as a class memeber.
In every method call I execute the command to get the results,I am doing so to avoid creation of connection and command every second, but I am afraid from exception occurs in this method that will break the connection or put the object in the invalid state.
This is my current implementation (Timer Handler)
static void GetBarTime(object state)
{
lock (_staticConnection)
{
SqlDataReader dataReader = null;
try
{
dataReader = _getMaxTimeCommand.ExecuteReader();
dataReader.Read();
_currentTick = dataReader.GetInt32(0);
}
catch (Exception ex)
{
//Log the error
}
finally
{
dataReader.Dispose();
}
}
}
What is the best practise?
MORE DETAILS:
I am doing this in a timer as there is another prorcess update my table every second, and there is another exposed method used by set of clients and called every second to get the latest value.
So instead of executing select statement every second for each client, I am doing it in a timer and update global variable that is used by the clients.
SqlConnection has pooling built in; you would see almost no difference if you used:
using(SqlConnection conn = new SqlConnection(connectionString)) {
conn.Open();
// your code
}
each time. And that can react automatically to dead (underlying) connections.
Currently you have a bug, btw; if the command fails, the reader will still be null... either check for null before calling Dispose():
if(dataReader !=null) {dataReader.Dispose();}
or just use using:
try
{
using(SqlDataReader dataReader = _getMaxTimeCommand.ExecuteReader())
{
dataReader.Read();
_currentTick = dataReader.GetInt32(0);
}
}
catch (Exception ex)
{
//Log the error
}
It can be pretty difficult to find out if an execption means that the connection is a dead duck. To be on the safe side, you could close and reopen the SqlConnection and SqlCommand whenever you encounter an exception, just in case. That doesn't cause any overhead when everything works alright.

Why use finally in C#?

Whatever is inside finally blocks is executed (almost) always, so what's the difference between enclosing code into it or leaving it unclosed?
The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.
Now, I'm guessing your question is why you should do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
When you can do this:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
The answer is that a lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. With the latter code, the "alwaysDoThis();" call won't execute if the code inside the catch statement issues a return or throws a new exception.
Most advantages of using try-finally have already been pointed out, but I thought I'd add this one:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
This behaviour makes it very useful in various situations, particularly when you need to perform cleanup (dispose resources), though a using block is often better in this case.
Because finally will get executed even if you do not handle an exception in a catch block.
any time you use unmanaged code requests like stream readers, db requests, etc; and you want to catch the exception then use try catch finally and close the stream, data reader, etc. in the finally, if you don't when it errors the connection doesn't get closed, this is really bad with db requests
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
if you don't want to catch the error then use
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
and the connection object will be disposed of automatically if there is an error, but you don't capture the error
Finally statements can execute even after return.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally, as in:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
is a guaranteed opportunity to execute code after your try..catch block, regardless of whether or not your try block threw an exception.
That makes it perfect for things like releasing resources, db connections, file handles, etc.
i will explain the use of finally with a file reader exception Example
with out using finally
try{
StreamReader strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
StreamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
in the above example if the file called Data.txt is missing, an exception will be thrown and will be handled but the statement called StreamReader.Close(); will never be executed.
Because of this resources associated with reader was never released.
To solve the above issue, we use finally
StreamReader strReader = null;
try{
strReader = new StreamReader(#"C:\Ariven\Project\Data.txt");
Console.WriteLine(strReader.ReadeToEnd());
}
catch (Exception ex){
Console.WriteLine(ex.Message);
}
finally{
if (strReader != null){
StreamReader.Close();
}
}
Happy Coding :)
Note:
"#" is used to create a verbatim string, to avoid error of "Unrecognized escape sequence".
The # symbol means to read that string literally, and don't interpret control characters otherwise.
Say you need to set the cursor back to the default pointer instead of a waiting (hourglass) cursor. If an exception is thrown before setting the cursor, and doesn't outright crash the app, you could be left with a confusing cursor.
Sometimes you don't want to handle an exception (no catch block), but you want some cleanup code to execute.
For example:
try
{
// exception (or not)
}
finally
{
// clean up always
}
The finally block is valuable for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.
Ahh...I think I see what you're saying! Took me a sec...you're wondering "why place it in the finally block instead of after the finally block and completely outside the try-catch-finally".
As an example, it might be because you are halting execution if you throw an error, but you still want to clean up resources, such as open files, database connections, etc.
Control Flow of the Finally Block is either after the Try or Catch block.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
with Exception
1 > 2 > 3 > 4 > 5
if 3 has a Return statement
1 > 2 > 3 > 4
without Exception
1 > 2 > 4 > 5
if 2 has a return statement
1 > 2 > 4
As mentioned in the documentation:
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
It is also worth reading this, which states:
Once a matching catch clause is found, the system prepares to transfer control to the first statement of the catch clause. Before execution of the catch clause begins, the system first executes, in order, any finally clauses that were associated with try statements more nested that than the one that caught the exception.
So it is clear that code which resides in a finally clause will be executed even if a prior catch clause had a return statement.

Categories