When can an exception in a .NET WinForms app just get eaten without being caught or bubbling up to a windows exception?

StackOverflow https://stackoverflow.com/questions/489071

Question

In several places in our code, we notice that if running under debugger it'll show that there's an unhandled exception in the code, however if running outside the debugger it will just ignore the exception completely as if it were caught. We have an exception handler that pops up an error submit dialog that's hooked up to Application.ThreadException and AppDomain.CurrentDomain.UnhandledException And neither of those appear to be catching them either. We also log our exceptions and nothing appears in the log.

What are some possible reasons for this?

Edit: It seems that it isn't dependent on the type of exception throw, but rather where it is thrown. This was tested by just adding:

throw new Exception("Test Exception");

It'll show up under debugger but doesn't show up outside, so in our case it's not a ThreadAbortedException or anything that's dependent on it being a specific type of exception.

Was it helpful?

Solution 2

Found one place where this could occur is if there's an exception in the UnhandledException event handler. An easy way to see this is this: In the Form.Load event handler throw any old exception. In the Application.ThreadException event put something similar to the following:

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
     string b = null;
     int i = b.Length;
}

Under debugger it'll show your exception was unhandled by user code, and then after that it'll show a null reference exception in the ThreadException handler, but if you run it outside the debugger it'll just swallow the exception like it was handled.

OTHER TIPS

There are some special exceptions that don't get bubbled up or caught, it sounds like you're dealing with one of them: see ThreadAbortException

If you try to modify the properties of a Windows Form control from a different thread the control was created in, you get an InvalidOperationException if there is a debugger attached, but it gets silently ignored otherwise.

More info on the issue can be found here:

http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx

Your code is invoked from the framework.

Sometimes, the framework wraps its calls in an exception handler.

So, if there's an exception in your code, it may be (if there's an exception handler there in the framework) caught and ignored by the framework.

Maybe the debugger shows it as "unhandled" because, although there's a handler in the framework, there's no handler in your code? Or, because there's something strange about the handler in the framework, for example that it's an unmanaged, structured exception handler?

Are you using .Net 1.0/1.1? There was a huge change in behaviour in the transition from 1.1 to 2.0. Before then exceptions raised on threads you created or ThreadPool threads would be swallowed silently by the frameworok and the thread would exit. Thankfully this behaviour has now been fixed.

From MSDN:

Change from Previous Versions

The most significant change pertains to managed threads. In the .NET Framework versions 1.0 and 1.1, the common language runtime provides a backstop for unhandled exceptions in the following situations:

  • There is no such thing as an unhandled exception on a thread pool thread. When a task throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then returns the thread to the thread pool.

  • There is no such thing as an unhandled exception on a thread created with the Start method of the Thread class. When code running on such a thread throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then gracefully terminates the thread.

  • There is no such thing as an unhandled exception on the finalizer thread. When a finalizer throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then allows the finalizer thread to resume running finalizers.

Kind of a stretch here, but could it be that you just have set your debugger to break when an exception is thrown, and not only for the unhandled ones?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top