Friday, September 29, 2006

Peek into the database during your unit test

Have you ever had the following problem?
You are debugging a unit test which has just inserted some records into your database. While the unit test is waiting on a breakpoint you want to see the result of the insert in the database. You start up SQL Query Analyzer type 'select * from customers' and hit . What happens? If you are lucky you get to see the table as it was before you started the unit test, if you are unlucky your query just 'hangs'. Now why is that?
Anyone who understands a little bit about transactions knows this must be because the insert is done inside a transaction which has not yet been committed. Therefore the result of the insert is isolated from any other database process or a table lock might even prevent you from reading the table at all.
When I ran into this (again) today I started thinking about it and found a solution which in fact is very simple. Before running your select * from customers you execute the command:


SET TRAN ISOLATION LEVEL READ UNCOMMITTED


The trick is that by setting the isolation level to 'read uncommitted' you can read the data that was inserted by the unit test code even though there might be table locks and the changes might eventually even get rolled back (which is usually the case in a unit test).

Sunday, September 24, 2006

Keep your hands off my stack traces!

When the first beta of the .Net framework was released one of the best features I thought was that the Exception.ToString() method shows you the stack trace from the place where the exception is thrown to where it is caught. Stack traces are your best friend when finding the cause of an unexpected exception. Back in the VB 6 time we spent a lot of effort harvesting this information ourselves.
This is why I get really upset when someone screws up the stack trace information by doing something like the following.


try
{
    // method call that might throw an exception at some deeper level
    some.Method();
}
catch (Exception ex)
{
    // some code to figure out what to do with the exception (maybe logging or whatever)

    // hmm in this case we do not really handle this exception after all, lets re-throw
    throw ex;
}



What is wrong with this code? It is the 'ex' behind the throw. When you re-throw an exception this way the stack trace information in the Exception object is cleared and it will appear to who ever catches it at a higher level as if the exception originated from the location where it is re-thrown, thereby loosing valuable information about the location where the exception really occurred.
Inside a catch block you are allowed to use trow; (without an exception). The C# reference doesn't say very much about this, except that it is used when re-throwing the current exception object in a catch clause. Sounds like it is pretty much the same as when you do explicitly throw the exception you just caught as in the code example.
There is however a big difference that is not directly clear from the documentation. When you use throw without an exception you are actually saying "lets pretend I never caught this exception". This causes the Exception to be thrown further up while preserving the whole stack trace from the original throw to the next catch up the call stack.
Now pretty please, with sugar on top, use throw; instead of throw ex; inside a catch block, and leave my stack trace alone!