-1

I have a bizzare issue that I am struggling to resolve:

I have a form that performs a number of different searches using LINQ queries. 99% of the time the code will execute fine without any errors what so ever, however, on total random occasions, my form falls over on the following line:

     'Find all tickets belonging to a user
     Dim _userTicketsList As List(Of Ticket) = Tickets.FindAll(Function(p) 
                 p.ticket_firstname.ToUpper = NewSearchString And 
                 CDate(p.ticket_created_at.Value.ToShortDateString) >= date1 
                 And CDate(p.ticket_created_at.Value.ToShortDateString) <= date2)

The error I get is Object Reference Not Set To An Instance Of An Object

From then on, any search will continue to bomb out on this line of code, until I restart my app. I execute the search again and everything works fine.

I cannot understand what is causing this error to occur. It can happen if .FindAll returns 0 results or if it returns any number of results.

Is there anyway I can determine what Object is trying to get set? I'm assuming its _userTicketsList but it doesn't make sense why sometimes it works and sometimes it doesn't.

I know it's probably hard to comment without seeing every bit of code, but is there anyway I can try and debug this differently? The debugger sits on this line of code for 23,000+ Ticket items, so I can't even work out if there is a specific Ticket that is causing the issue.

Any help or direction is greatly appreciated. Thanks

Panagiotis Kanavos
  • 90,087
  • 9
  • 138
  • 171
Riples
  • 1,105
  • 1
  • 16
  • 50
  • You could try Debug.Assert to make sure your assumptions are fine. Are you sure if p.ticket_firstname, p.ticket_created_at etc are all non null? – Sruti Jan 29 '15 at 07:14
  • 1
    *Tickets* or *p*, *ticket_firstname* or *ticket_created_at* (Nullable DateTime?) can also give a NRE. Can one of these be null? If so, you have to check for *null* before using them. – Loetn Jan 29 '15 at 07:15
  • @Loetn I do understand this, however, it doesn't explain why most of the time this code will execute without error. This search happens on every thing that is searched, sometimes resulting in 0 results, sometimes more. If one of these variables were null (which they can be) wouldn't this cause the code to bomb everytime? – Riples Jan 29 '15 at 07:21
  • Well, you could of course split it up into three lines, so it will be easier for you to spot the item causing the exception. `Dim _userTicketsList As List(Of Ticket) = Tickets.FindAll(Function(p) p.ticket_firstname.ToUpper = NewSearchString)` `_userTicketsList = _userTicketsList.FindAll(Function(p) CDate(p.ticket_created_at.Value.ToShortDateString) >= date1)` `_userTicketsList = _userTicketsList.FindAll(Function(p) CDate(p.ticket_created_at.Value.ToShortDateString) <= date2)` – sloth Jan 29 '15 at 08:01
  • Either the list is null or one of the object properties you are using is null. Put a breakpoint inside the lambda and add watches or just hover over each property to find which one is null. – Panagiotis Kanavos Jan 29 '15 at 08:17
  • Is `created_at` nullable? If so, you should *not* access its value property without first checking for null. The fact that the code executes "most of the time" means nothing - it works when it doesn't encounter null values. Also, why are you converting a date to a string then back to a date??? Just use DateTime.Date if you want a date without the time – Panagiotis Kanavos Jan 29 '15 at 08:20
  • Another option is to extract the lambda to a separate function, so when the exception occurs again you'll have easier access to the local variables. Also make sure to check the Locals and Auto debugger windows. They probably already show the objects that caused the problem – Panagiotis Kanavos Jan 29 '15 at 08:23
  • I have managed to simulate the error with a different statement now and can crash my app every time. I have found that if the LINQ query returns no results, it can't assign `Nothing` to the variable, instead throwing an error `Object Reference Not Set....`. Can this be avoided? – Riples Feb 04 '15 at 05:15

1 Answers1

0

Well, you can basically decorate your lambda expression with try catch statements, just to log / do something with the error.

'Find all tickets belonging to a user
Dim _userTicketsList As List(Of Ticket) = Tickets.
    FindAll(Function(p)

                Dim condition1 As Boolean
                Dim condition2 As Boolean
                Dim condition3 As Boolean

                Try
                    condition1 = p.ticket_firstname.ToUpper = NewSearchString
                Catch ex As Exception
                    'Do Something
                End Try

                Try
                    condition2 = CDate(p.ticket_created_at) >= date1
                Catch ex As Exception
                    'Do Something
                End Try

                Try
                    condition3 = CDate(p.ticket_created_at) <= date2
                Catch ex As Exception
                    'Do Something
                End Try

                Return condition1 And condition2 And condition3

            End Function)

Code Addition Edited Per OP's comment

If _userTicketsList.Any = False Then
    _userTicketsList = Nothing
End If

I also wanted to make sure you are aware of the difference in using And vs. AndAlso clause in vb.net.

When writing something like If(A and B) both A and B will execute.

While using AndAlso, will not execute B if A is false, since you are using And, I thought I'll mention it.

Y.S
  • 1,703
  • 2
  • 15
  • 26
  • Y.S I have implemented your code which allows me to step through the actual LINQ query now, however, the `Catch` never seems to catch the error. I have since found that the problem lies when the `FindAll` (or `Find`) statement returns nothing (0 results) it looks like it can't assign Nothing to the variable. Instead it throws an error. How can I return `Nothing` if no results are found in the query? – Riples Feb 04 '15 at 05:13
  • Just add an IF statement which checks for it, and if the condition is true (I.e.) no results, set the TicketList variable to Nothing. Is that what you need? – Y.S Feb 04 '15 at 05:25
  • Could you possibly update your example to reflect that change please. – Riples Feb 04 '15 at 05:36
  • see my edit, is that you want? – Y.S Feb 04 '15 at 05:39
  • Sorry, but how can I test for `userTicketList.Any` when it throws an error before assigning anything to that variable? I'm assuming I add the check after running the `FindAll` statement? If so, the `FindAll` is throwing the error before I can even check to see if `_userTicketList` is set to anything. – Riples Feb 04 '15 at 05:48
  • So that means that the Tickets variable is Nothing, and therefore, you are getting a NullReferenceException, when trying to code a LINQ query on it. – Y.S Feb 04 '15 at 05:50
  • Place the IF condition before the LINQ query code. Pseudo: If(Tickets IsNot Nothing) Then Run LINQ Query. Makes sense? – Y.S Feb 04 '15 at 05:52
  • Yes makes sense thankyou. Just don't understand why I'm getting the error if no results are returned and I'm not trying to reference the variable?? But anyway, I will alter my code to reflect your changes. – Riples Feb 04 '15 at 06:01
  • But your are referencing it, by writing Tickets.FindAll you are referencing Tickets. If tickets is Nothing, You get a NullReferenceExcpetion. Tell me which part of it is not clear, and I'll try to explain it to you – Y.S Feb 04 '15 at 06:05
  • Ah okay...I understand now. Sorry for the run-about! Anyway, I appreciate your help and your examples and replies have helped me solve my issue. Much appreciated. Plus I now have a better understanding of NullReferenceErrors. Thanks – Riples Feb 04 '15 at 06:08
  • Glad to help, good luck. – Y.S Feb 04 '15 at 06:09