Friday, October 16, 2009

Logging the Stack Trace

Codes can be downloaded here

Stack trace is very important in locating exceptions because unlike the Message property, it can pinpoint the exact location of the line that throws the exception. Unfortunately, developers seldom log the stack trace for 2 reasons:

  1. They can be very long which in turn requires a large storage capacity
  2. The information don’t help that much because the methods are listed in reverse order.

The size of the stack trace depends on where the method that throws the exception is located in the call stack. Take for example adding of record functionality in this application:

image

The function has a very shallow stack which is initiated by a button click and terminates in the database. This is illustrated by the call stack diagram below:

Button click in Default.aspx  -----calls----> Entity Framework Model -----calls------> Database

If a line in the “button click” method causes an exception, say a database integrity violation,  the first method in the stack trace is not not the “button click” but the one that detects the violation which is shown here:

at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) at System.Data.Objects.ObjectContext.SaveChanges(Boolean acceptChangesDuringSave) at System.Data.Objects.ObjectContext.SaveChanges() at WebApp._Default.btnException_OnClick(Object sender, EventArgs e) in C:\Users\Vanni\Documents\Visual Studio 2008\Projects\StackTraceSplit\WebApp\WebApp\Default.aspx.cs:line 28

For the developer searching for the bug in a production environment, the last method in the trace is the most important because that is where he’s going to start the search. To make his life easy, one can write a extension methods for System.Exception that can reverse the order of the stack trace and retrieve only a portion of it, usually the ones which the developer has access to. Extension methods are user-defined methods that can attached to an object which implementation is off-limit to developers. The method should adhere to the following guidelines in order for it to qualify as an extension method

  1. It has to be static
  2. It has to have a return value
  3. The first parameter should be in the form “this <object to extend> parameter value”

The extension methods for the predicament discussed may look like the ones below. Note that it’s a good practice to specify the class as static because this ensures that all methods should be static too.

 image

The first method splits the entire stack trace into arrays by using the characters “ at “ as the separator and reverses the order. The second is an overload which accepts a number of stack to return, starting from the top. The third method returns only one big chunk of the stack trace and is intended for logging.

When running the following codes,

image

a portion of the result would look like this:

image

Now that will definitely make a debugger’s life easy!

Sunday, October 11, 2009

Aliasing a class? Whoa!

I accidentally discovered a feature in C# that I thought only possible with C/C++ – aliasing a class. I’ve been coding .NET for years but never have I encountered examples or extensive discussion on this. I will not be a fan of this because I’m sure this also have the same problems inherent to the C/C++ equivalent. One justification for using this may be for shortening of a class name, but again we don’t have to type who needs to type the entire class name? Don't we have Intellisense to help us with that. Besides, if class has very unwieldy long name, it wouldn’t hurt to contract some words or better, redesign it because it may not be cohesive all along.
image

Wednesday, October 7, 2009

“Nullable object must have a value.” – could be a sign of something serious

At first glance, the InvalidOperationException with the message “Nullable object must have a value.” is probably the most senseless of all .NET exceptions. This is because the message is very misleading when one takes it by its face value. The most logical conclusion a reader can derive is that it’s something about failing to assign a non-null value to a Nullable<T> object. Microsoft could have used a much better verbiage because what’s actually triggering the exception is an attempt to perform an action to the Nullable<T> object which value happens to be null. In other words, it’s about an invalid action, not value.
image
Figure 1 – A message that can leave you dumbfounded
Unfortunately, the capability of Visual Studio in detecting null nullable is limited only to uninitialized fields. If the nullable object is a property, then all you can do is sit and wait for the bomb to go off. In Figure 2, the properties SampleClass.NullableBool and Program.NullableBool are never checked by Visual Studio whereas _nullableBool cannot escape the scrutiny.
image
Figure 2 – Visual Studio can help detect only uninitialized nullable fields
Figure 3 shows the most common mistakes that trigger the exception. The first case is when the Value property is called to extract the encapsulated native type. The second case is quite common among new programmers where instead of calling Value, a cast is performed on the nullable object.
image
Figure 3 – Be on the lookout for lines similar to these
Bear in mind though that calling ToString() on a null nullable is perfectly legal as long as it’s initialized. It simply yields a blank which is what exactly we want in the UI.
image
Figure 4 – It’s safe to call ToString as long as the nullable is initialized

There Could Me Something More

When you’re done cursing Microsoft, do yourself a favor and go back to your codes. The message could be a sign of a more serious type of bug lurking somewhere. This is because it’s possible that nullables are used in boolean conditions without the benefit of a prior nullability check. If this is the case and the coder does not call the Value property, the compiler does not complain at all. It simply evaluates the condition as false!
image
Figure 5 – A null nullable is always evaluated as false
In the business rules of your application, it might be that a null is equivalent to a false and in this case, you could care less about codes similar to Figure 5. However, the fact that 3-value logic is already allowed to permeate in the application also means that null deserves a separate treatment altogether. A null could mean “I don’t know”, “not yet”, or “maybe”.
image
Figure 6 – This block can wreak havoc in your application.

Defensive Coding

Nullable<T>.HasValue can be used to check if the value is null. You usually use this whenever a null value is treated differently as illustrated in the snippet below:
image
Figure 7 – Using HasValue prevents exception and aids in the 3-value logic evaluation
In the rare cases where a null means false or any valid value of a type, one can use the coalesce C# operator ?? as shown here:
image
Figure 8 – The coalesced operator is handy when null value can be interpreted in some other way
In the next release of .NET, I hope we could get a much more meaningful message, something like “Attempting to perform action to a Nullable<T> is not allowed when its value is null.” Whatcha think?