I am responsible for an F# WPF application. It emails me when an unhandled exception occurs. Most of the time, I'm able to identify the source of the exception from the error message and stack trace. However, I occasionally get a message like the following, which does not include any of my code in the stack trace.
Summary:
Object reference not set to an instance of an object.
--------------
Details:
System.NullReferenceException:
Object reference not set to an instance of an object.
at Microsoft.FSharp.Control.CancellationTokenOps.Start@1234-1.Invoke(Exception e)
at <StartupCode$FSharp-Core>.$Control.loop@435-40(Trampoline this, FSharpFunc`2 action)
at Microsoft.FSharp.Control.Trampoline.ExecuteAction(FSharpFunc`2 firstAction)
at Microsoft.FSharp.Control.TrampolineHolder.Protect(FSharpFunc`2 firstAction)
at <StartupCode$FSharp-Core>.$Control.-ctor@520-1.Invoke(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
What clues are available in this stack trace that might help me identify the source of this exception?
For example, I'm assuming the original exception is being thrown within an async
computation. (The majority of my async code is based on F# async blocks.) Could my NullReferenceException
have occurred anywhere in an async
block? I notice that the exception occurred within a Start()
method. Or is it? That Start()
method takes an Exception
instance so perhaps the exception was thrown before that. Does that tell me anything? I wonder if someone is familiar enough with the Microsoft.FSharp.Control.Trampoline
to point me in the right direction.
By the way, in my error handling code, I am careful about checking all the InnerExceptions
and handling AggregateExceptions
. So I think this is all the information available in the Exception instance, but I could be wrong.