Unhandled Exception in Winforms Application
Asked Answered
H

2

8

I have a simple WinForms app that is used to enter test cases. Ever since I upgraded this application to .NET 4.0 and added a new tab page to the tab page control for validating XML against XSD schema the application has been randomly crashing. I've been unable to reproduce the exception.

The error my QA guy receives is the generic Windows message:

TestCaseViewer has encountered a problem and needs to close. We are sorry for the inconvenience.

To try to get to the real error I've added the following code to the beginning of the Main method of program:

        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        Application.ThreadException += Application_ThreadException;

The event handlers look like this:

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        try
        {
            MessageBox.Show(e.Exception.ToString(), @"Thread Exception", 
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        finally 
        {
            Application.Exit();    
        }
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        try
        {
            var ex = (Exception)e.ExceptionObject;
            MessageBox.Show(ex.ToString(), @"Unhandled Exception",
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
        finally 
        {
            Application.Exit();    
        }
    }

Unfortunately this hasn't helped and whatever is thowing the error continues to do so in a way that generates the unhandled error that is bubbling up to the OS.

Can anyone give me any other ideas about trapping this exception?

Hughs answered 19/2, 2011 at 5:23 Comment(2)
Stacktrace? MessageBox.Show(e.Stacktrace);Aishaaisle
As long as the stack trace is not null it will be returned when ToString() is called on the exception.Hughs
I
11

Try adding the following to your app.config

<runtime>
   <!-- the following setting prevents the host from closing when an unhandled exception is thrown -->
   <legacyUnhandledExceptionPolicy enabled="1" />
</runtime>
Inapproachable answered 11/3, 2013 at 21:16 Comment(1)
I don't really know what this does, but it looks very suspicious. You need to fix the damn problem, not pat yourself on the back for forcing your program to soldier on blindly in an unknown state.Punctuation
M
2

If you're using Visual Studio, you can set it to break on all unhandled exceptions and even any time that an exception is thrown, regardless of whether or not it is handled by your code.

To do this, select "Exceptions" from the "Debug" menu. You'll get a dialog box that looks like this:

  Visual Studio Exceptions dialog

If you really want to get serious, try checking all of the boxes. Then, find out from your QA guy what exactly is being done to trigger the exception, and reproduce those actions exactly while running under the debugger within the development environment. Whenever the exception is thrown, Visual Studio will break and you'll see the offending line of code along with a complete stack trace.

Messere answered 19/2, 2011 at 6:20 Comment(8)
I actually do have that setting checked in my IDE. The problem is I can't reproduce the error following the same steps as he is just clicking around in a datagrid. The error doesn't manifest itself in the same fashion twice in a row. I have a feeling it is something bad in the databinding wireup or code handling position changes in the grid.Hughs
@Loathian: This tester is in your company? Bring him to your computer and have him reproduce the bug. I'm not sure what other kind of answer you're looking for here. It's next to impossible to fix a bug you can't repro. Every bug database has an option to close bugs as "no repro" for that reason. Things might be different if this were a customer at a remote location with special needs, but if you can't reproduce it with the help of your own QA department, I doubt anyone on here can help you.Messere
It is a tester at my own company, actually sits right across from me. If he can create the error again I'm going to have him capture it with some debugging tools to see if we can get the stack trace that way. I was really just looking for someone to review my exception handling code to see whether or not I'd made any mistakes.Hughs
@Loathian: Ah, I see. Well, I believe there are certain types of exceptions that even the most perfectly written exception-handling code in the UnhandledException event handler won't catch. Setting Visual Studio up to break when any exception is thrown is the most foolproof way I know to work around that. You said that your code hasn't helped and implied that the error continued to bubble up the stack. I assumed that meant it was reproducible, but you weren't able to break when it occurred to get a stack trace. The method I've demonstrated will work for that assuming you can get it to occur.Messere
We tracked it down today ... the error is being throw from a winforms control we are using to render XML in a 'pretty' format. Looks like the error is being thrown when dispose is being called on the control. The control is: System.Windows.Forms.WebBrowser ... here is the error information: System.Windows.Forms.UnsafeNativeMethods+IOleObject.SetClientSite(IOleClientSite) at System.Windows.Forms.WebBrowserBase.TransitionFromRunningToLoaded() at System.Windows.Forms.WebBrowserBase.TransitionDownTo(AXState) at System.Windows.Forms.WebBrowser.Dispose(Boolean)Hughs
@Loathian: No idea what could be causing that exception; I haven't seen it before. You should update your question to include the new information. Mark it as an edit at the bottom. That will "bump" it up the list, and cause it to get some attention from fresh eyes.Messere
I saw you mentioned in another post that a properly designed app should call Application.Exit() ... my exception handling code includes this. Is that ok? What happens if I have another error get thrown in the Form Closing event? Should I check for a global error state and skip that code?Hughs
@Loathian: I think I said that a properly designed app should not call Application.Exit. The reasoning behind that statement is that when you close all of the forms you've opened, your application will close automatically. There's nothing inherently wrong with calling Application.Exit, but having to do so in order to get your app to quit is a sign that you've mis-managed resources and aren't keeping track of the form objects you've created/displayed. It's perfectly reasonable in your finally block, since you're explicitly guarding against exceptions that might be thrown.Messere

© 2022 - 2024 — McMap. All rights reserved.