I have an odd problem in one of my applications that I can’t figure out. I track errors in the application in an error log and admin emails get fired whenever something fails. Every once in a while the application fires errors telling me that certain fields in a Table don’t exist. However, it works most of the time with the same exact (as far as I can tell) path through the application and I’ve never been able to duplicate this error at all. Even using the same URLs as the failure scenario (all requests get logged so I can look up by IP and try to trace).
Basically what happens is that the page downloaded creates a DataTable and more specifically a DataRow that is used to display the data. The code then reads one of the rows in the table. The SQL is a select * on a specific row in this case – pretty straight forward stuff. The table on the server definitely includes the field that supposedly isn’t there.
There’s error checking in the data retrieval (as part of the bus object), so any data access error would result in a handled error that wouldn’t fire off into the error logs like this. The strange thing is that other fields in the same datarow are accessed before the code accesses this particular column (Image – which is merely a text field).
The value wouldn’t be null either. If I go to the same URL it of course never fails for me… Sooooo… I’m baffled how this code could fail infrequently and in just this way. It makes no sense…
This is the block of relevant code in this page’s Page_Load():
// *** Retrieve the inventory item for checking stock and binding
// this is where the DataRow gets retrieved
// a DAO error would result in a false value here
if (!this.IvtItem.GetItemBySku(lcSku))
{
MessageDisplay.DisplayMessage("Invalid Item",
"The item you selected is no longer available. " +
"If you typed the Url in manually make sure the SKU is typed correctly.");
return;
}
// *** Data Row mapping to typed object
this.rowItem = this.IvtItem.GetTypedDataRow(false);
// *** If this item has redirection set up go there straight out
if (this.rowItem.Redirect != "")
{
Response.Redirect( this.rowItem.Redirect );
return;
}
// *** We'll bind in code here because we need to fix up a few things
this.lblTitle.Text = rowItem.Descript;
// *** Force HTML linebreaks into the field text
this.lblDescription.Text = wwUtils.DisplayMemo( rowItem.Ldescript );
// *** Display price as Currency
this.lblPrice.Text = rowItem.Price.ToString("C");
// *** Don't allow adding if stock is out
if ( !IvtItem.CheckStock(1))
{
this.btnSubmit.Enabled=false;
this.btnSubmit.Text = "Out of Stock";
}
// *** !!! THIS IS WHERE THE ERROR OCCURS !!!
if (!wwUtils.Empty( rowItem.Image ) )
this.imgProduct.ImageUrl = "itemimages/" + rowItem.Image;
else
this.imgProduct.Visible = false;
Notice that the code above accesses a bunch of other fields in the table before it gets to image, so the DataRow is there. How could it be that the SQL statement would not return the field?
The bus object method looks like this:
public bool GetItemBySku(string Sku)
{
int lnCount = this.Execute("select * from " + this.Tablename +
" where sku=@Sku",this.Tablename,
this.CreateParameter("@Sku",Sku));
if (lnCount < 0)
{
this.SetError(this.Data.ErrorMessage);
return false;
}
if (lnCount < 1)
{
this.SetError("Item not found.");
return false;
}
this.DataRow = this.DataSet.Tables[this.Tablename].Rows[0];
return true;
}
It doesn’t get much simpler than this. Either it works and a row comes back or it doesn’t in which case the thing returns false and the mainline displays an error.
Anybody ever seen anything like this or see something that I’m just outright missing here? Could it be that Sql Server is sometimes not returning a field in a select * query??? What's odd too is that when the error occurs I usually see 3 or 4 in a row so the user is probably retrying and it keeps on failing with the same error.