I've had an asp.net website running live on our intranet for a couple of weeks now. I just got an email from my application_error emailer method with an unhandled exception.
Here it is (ive cleaned up some of the paths to make it better displayed)
Exception : Object reference not set to an instance of an object. Stack Trace : at System.Collections.Generic.Dictionary
2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary
2.Add(TKey key, TValue value) at TimesheetDomain.DataMappers.StaffMemberData.ReadStaff(SqlDataReader reader) in TimesheetDomain\DataMappers\StaffMemberData.cs:line 362at TimesheetDomain.DataMappers.StaffMemberData.GetStaffMember(String name) in TimesheetDomain\DataMappers\StaffMemberData.cs:line 401
at TimesheetDomain.ServiceLayer.TimesheetManager.GetUserFromName(String name) in TimesheetDomain\ServiceLayer\TimesheetManager.cs:line 199
at UserVerification.GetCurrentUser() in \App_Code\UserVerification.cs:line 29 at WebTimesheets.OnInit(EventArgs e) in \WebTimesheets\WebTimesheets.master.cs:line 159
at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Control.InitRecursive(Control namingContainer) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Basically it looks like its erroring at my ReadStaff method which reads a data reader to build staff member objects. Here is the bit of code:
while (reader != null && reader.Read()) { StaffMember newMember = null; string firstName = reader["FirstName"].ToString(); string lastName = reader["LastName"].ToString(); int staffID = (int)reader["StaffID"]; int employSection = (int)reader["EmploySection"]; StaffType employType = (StaffType)employSection; string emailAddress = reader["EmailInt"].ToString(); int employCode = (int)reader["ibbwid"]; //check if they are an admin staff member if (IsAdminStaff(employType)) { newMember = new AdminOfficer(firstName, lastName, employType, staffID, emailAddress, employCode); } else { //check if they are a supervisor if (IsASupervisor(staffID)) newMember = new Supervisor(firstName, lastName, employType, staffID, emailAddress, employCode); else newMember = new StaffMember(firstName, lastName, employType, staffID, emailAddress, employCode); } //add to identity map if (!_staffMembers.ContainsKey(staffID)) _staffMembers.Add(staffID, newMember); //****THIS IS LINE 362***** else _staffMembers[staffID] = newMember;
(Line 362 is 3rd last line) I'm using an identity map (just read fowlers book on patterns and thought it was a good idea - may have done it wrong, happy for comments) but thats not overly relevant as later on I use the newMember object elsewhere so if I remove that block the nullreference will happen then.
I am struggling to see how on earth newMember is null in the 3rd last line there (which is the line that errored)
Resharper/VS dont give me a warning that it could be null - because theres the 3 constructors which i choose from.
Can anyone suggest where I can look to try and fix this error? It's only happened once and that method has been called thousands of times since the site went live.
Thanks
[EDIT] As Requested, here's the IComparer for staff member
/// /// Comparer for staff members - compares on name /// public class StaffMemberComparer : IComparer { public int Compare(object x, object y) { //check they are staff members if (x is StaffMember && y is StaffMember) { //do a simple string comparison on names StaffMember staffX = x as StaffMember; StaffMember staffY = y as StaffMember; return String.Compare(staffX.FirstName, staffY.FirstName); } throw new Exception("This is for comparing Staff Members"); } }
and its used in the IComparable implementation
/// /// IComparable implementaiton /// /// object to compare to /// public int CompareTo(object obj) { StaffMemberComparer comparer = new StaffMemberComparer(); return comparer.Compare(this, obj); }