Search code examples
c#visual-studio-2012unhandled-exception

Unhandled Exception next line or exit


[update 2: Problem solved, see my comment below and in my other post. Hope this helps someone.]

[update: The response to my other question Detecting Exceptions During Beta Testing, which served as the basis of this question is flawed. Inside the Visual Studio both 2010 and now 2012 works great. The exception handler gets called, okay after VS breaks at the line and I say to continue. I decided to test outside the VS2012 IDE, good thing for that. The OS traps the bug, shows the standard an "An Unhandled Exception Occurred" dialog giving the details along with a continue and quit buttons. Selecting continue, just continues the application with no trapping into my uber exception handler. Selecting quite, whites-out the application and displays the standard close window dialog. The quit button also does not call my uber handler.

The purpose is so that my exception handler gets called. I do not need an uber exception handler if I am working inside the VS2012 IDE. The purpose of the handler is for end users and beta testers, namely anyone other than myself and who will not have my development station.

The code below does not work outside the IDE. As such, the two buttons Close App and Continue are meaningless, as the exception handler never gets called. While running under the IDE and playing with the code (why is that not an abject waste of my time?), the continue does not continue and the exit does not exit. I just see the same exception over and over again. Yes, I am tring the posted possible answer.

I really would think that this topic would be well worn and solved with .Net 4.5. ]

I added an unhandled exception handler, which is indepedent of my main form, which I added just prior to the Application.Run(new frmMain()) call. The handler works as expected, no issues.

Questions: 1. Is it possible, and if so how, to forcefully close / end the offending form (close app, basically)?

I added a button on the main form and in the OnClick event, I simply divided by zero, so as to focefully simmulate something bad. I am running with the VS2012 debugging environment. Naturally, I hit first the offending line, which VS allerted me to, however upon continuing execution, I hit my unhandled exception handler. Inside that handler, one option is to end execution. I executed "Application.Exit()" but that had no effect. I kept going right back to that offending line.

  1. Is it possible to programatically from the exception handler to have execution continue from the next line?

Simply returning just gets me right back to that point.

I already know of try/catch blocks, but the purpose here is to catch unhandled exceptions that I do not expect and that in worst case, I can be sent a meaningful crash report that I generate from that handler.

JMK asked for some sample code, but not really sure what that would entail.

I throw up a dialog in response to an unhandled exception. There are 4 buttons, two for the purpose of this posting. The first button allows the user to continue, while the second button terminates the application. At least, that is the thought.

        private void cmdContinue_Click(object sender, EventArgs e)
    {
        // Close this dialog and attempt to resume.
        this.DialogResult = DialogResult.OK;
        this.Close();
    }

    private void cmdExitApp_Click(object sender, EventArgs e)
    {
        // Close this dialog and attempt to resume.
        this.DialogResult = DialogResult.OK;
        this.Close();

        // Exit the application.
        Application.Exit();
    }

The continue block, at least from within VS2012 IDE, merely keeps at the offending line. Ditto for the exit block.

As far as my exception goes, the exception can be anything. That is why I wrote it. My dedicated exception is merely to test out the code and then the button goes bye-bye. I am trying to be diligent and create a perfect non-breaking application, however that goal is illusive and until that time this block. The other purpose of this mechanism is for beta testers to report bugs to me.

Here is the code for my ultra quick and dirty unhandled exception. I had to be tricky, because simply dividing by zero would get caught by the compiler. By the way, unhandled exceptions usually occur not on a specific line that I write, but in calls to someone else's code, inside a method.

        private void button1_Click(object sender, EventArgs e)
    {
        // Attempt to throw and unhandled exception to test out the unhandled exception handler.
        int iDivider = 0;
        int iResult = 5 / iDivider;
    }

Here is another code block, namely the starting of the test application.

        public static frmMain FormMain = null;

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        // 
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // Turn on global unhandled exception handling.
        cExceptions.Initialize();

        // Run the application load tasks manually, as Windows will not call this event until the show.
        Program.FormMain = new frmMain();

        Application.Run(Program.FormMain);
    }

Someone asked for my exception handler, so here it is. Basically, Microsoft gave the sample.

    /// <summary>
/// Based on example at http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
/// </summary>
internal static class cExceptions
{
    [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
    public static void Initialize()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
    }

    static void MyHandler(object sender, UnhandledExceptionEventArgs args)
    {
        Exception ex = (Exception)args.ExceptionObject;


        // Log the exception to disk.

        // Show the exception information to the user.
        using (frmExceptions oException = new frmExceptions())
        {
            // Set the exeption information.
            oException.oEx = ex;

            // Show the dialog.
            oException.ShowDialog();
        }

        Console.WriteLine("MyHandler caught : " + ex.Message);
    }
}

Thanks in advance.


Solution

  • Okay, the Google Uberlord took pitty upon me and I found this wonderful article solving the problem. Praise to the almighty Google.

    Here is the link: http://www.switchonthecode.com/tutorials/csharp-tutorial-dealing-with-unhandled-exceptions

    Basically, JRadness had the right idea, just slightly in error. He should have used

    Application.ThreadException += 
        new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    

    rather than

    AppDomain.CurrentDomain.UnhandledException += 
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    

    The author on Switch on the Code talked of three methods, the first of which is what JRadness proposed and does not work for Windows forms.

    The autor even solved my other question of Continue and Abort. The OS got bypassed. Here is his event handler.

    public static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        DialogResult result = DialogResult.Abort;
        try
        {
            Exception ex = (Exception)e.Exception;
            MessageBox.Show("Whoops! Please contact the developers with the"
                 + " following information:\n\n" + e.Exception.Message + e.Exception.StackTrace,
                 "Application Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
        }
        finally
        {
            if (result == DialogResult.Abort)
            {
                Application.Exit();
            }
        }
    }
    

    Yeah!!