Monday, August 29, 2011

How a small typo caused an infinite loop and wasted half a day

I recently made a few rather minor changes to my .NET website. One of these changes introduced a bug, a "request has timed out" error that could be reliably replicated. Finding the cause took a whole afternoon.

One of the changes consisted of adding a column to one table in a SQL Server database and a few lines of C# code to read and display the value of that column. Here's the class where I added the new field, displayName:

public class MenuSize
{
private int menuSizeID;
private string displayName;
private int displayOrder;
private string name;
private int sizeID;
private bool showName;
private int menuCategoryID;

public string DisplayName { get { return displayName; } set { displayName = value; } }
public int MenuSizeID { get { return menuSizeID; } set { menuSizeID = value; } }
public int DisplayOrder { get { return displayOrder; } set { displayOrder = value; } }
public int SizeID { get { return sizeID; } set { sizeID = value; } }
public string Name { get { return name; } set { name = value; } }
public bool ShowName { get { return showName; } set { showName = value; } }
public int MenuCategoryID { get { return menuCategoryID; } set { menuCategoryID = value; } }
}

Note the line private string displayName;. I typed it wrong, putting diplayName instead of displayName.

Then when I added the line public string DisplayName { get { return displayName; } set { displayName = value; } }, I relied on Visual Studio's IntelliSense to fill in the variable name displayName. Because of my typo, displayName with a lowercase "d" didn't exist, and IntelliSense put in DisplayName with a capital "D". As a result (which I didn't notice), the line read public string DisplayName { get { return DisplayName; } set { DisplayName = value; } }.
Since this property sets DisplayName to itself, an infinite loop results! Just to make it really hard to find this bug, the method that instantiates MenuSize is inside a WSDL web service, and my web site calls the web service. So all I could tell was the call to the web service method was timing out. It took me about 6 hours of troubleshooting to figure out why. All because of a stupid missing letter "s" in displayName!