0

In an attempt to make this question a more Minimal, Complete, and Verifiable example, I am starting from scratch and trying to reproduce the problem in a minimal way. Please standby for new Question link

Problem Reproduced and Isolated Here

I've attempted to implement a global unhanded exception handler.

I have a WFA (Windows Form App).

In the Program class, I impliment the following code

    static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {   
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(Utility.UnhandledExceptionOccurred);
        Application.ThreadException += new ThreadExceptionEventHandler(Utility.UnhandledExceptionOccurred);
        if (!EventLog.SourceExists("TestEventSource"))
        {
            EventLog.CreateEventSource("TestEventSource", "TestEventLog");
            MessageBox.Show("EventLog and Source Created. Restart Please");
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }


}

This is the Utility class with the Event Handlers

    static class Utility
{
    public static void UnhandledExceptionOccurred(object sender, UnhandledExceptionEventArgs e)
    {
        MessageBox.Show("This Program Has Crashed\r\nPlease report this to nearest IT specialist " +
            "and restart the program");
        Exception E = (Exception)e.ExceptionObject;
        var errMsg = "UNHANDLED EXCEPTION \r\n";
        errMsg += "OUTER: " + E.Message + "\r\n";
        Exception Inner = E.InnerException;
        int i = 1;
        while (Inner != null)
        {
            errMsg += "INNER " + i.ToString() + ": " + Inner.Message + "\r\n";
            Inner = Inner.InnerException;
            i++;
        }
        errMsg += E.StackTrace;
        EventLog.WriteEntry("TestEventSource", errMsg, EventLogEntryType.Error);
        Application.Exit();
    }

    public static void UnhandledExceptionOccurred(object sender, ThreadExceptionEventArgs e)
    {
        MessageBox.Show("This Program Has Crashed\r\nPlease report this to nearest IT specialist " +
            "and restart the program");
        Exception E = e.Exception;
        var errMsg = "UNHANDLED EXCEPTION \r\n";
        errMsg += "OUTER: " + E.Message + "\r\n";
        Exception Inner = E.InnerException;
        int i = 1;
        while (Inner != null)
        {
            errMsg += "INNER " + i.ToString() + ": " + Inner.Message + "\r\n";
            Inner = Inner.InnerException;
            i++;
        }
        errMsg += E.StackTrace;
        EventLog.WriteEntry("TestEventSource", errMsg, EventLogEntryType.Error);
        Application.Exit();
    }
}

When I cause an exception in the main UI thread, This code works perfectly, catching the exception, writing to system event log, and exiting.

However, say I've got a new class in the same namespace.

    class Foo
{
    public Foo()
    {
        throw new Exception("A");
    }

}

Then in Form1_onLoad I execute the following code

        public void FormLoaded(object sender, EventArgs e)
    {
        var F = new Foo();
    }

The exception is raised, but never caught.

So far as I can tell, there is no second thread running in the background which I have to implement new UnhandledException Handlers for. Is there?

What is going on here? if my classes are all in the same namespace, why won't these unhandled exceptions get caught by the handles in Application?

Some More Source

    {

    public EventLog Log = new EventLog();
    Person P;
    public Form1()
    {
        InitializeComponent();
        Log.Source = "TestEventSource";
        Log.WriteEntry("Form Initialized and Running");
        throw new Exception("Exeption here is Caught");
    }

    public void FormLoaded(object sender, EventArgs e)
    {
        var F = new Foo(); //Exceptions here are not caught
    }
}

NO, I am not raising the Exception in the constructor for Form1() at the same time that I create a new Foo() in FormLoaded. Just to clarify. It's Either one or the other. When I raise the Exception in Form1() constructor, it is caught. When I do not Raise said exception in Form1() Constructor, and Create a new Foo() in Form1Load, the Exception is NOT caught.

tgabb
  • 349
  • 3
  • 12
  • There's a lot of code here in multiple classes - please try to reduce this to a [mcve] that we can easily copy/paste/compile/run - I wouldn't expect it to be more than 30 lines just to demonstrate this. – Jon Skeet Aug 06 '17 at 08:27
  • Sorry about that. Lesson learned. – tgabb Aug 06 '17 at 15:33
  • @JonSkeet I was able to reproduce and isolate the problem. https://stackoverflow.com/questions/45534142/exception-raised-by-timer-elapsed-not-caught-by-attempted-global-exception-event – tgabb Aug 06 '17 at 16:31
  • Why did you create a second question? You should have edited *this* question. – Jon Skeet Aug 06 '17 at 16:35

1 Answers1

1

I copied most of your code, replaced your exception-handling-code with just a Debugger.Break() and skipped the EventLog stuff and run it. Creating Foo in OnLoad calls the handler with ThreadExceptionEventArgs, creating Foo in the forms constructor calls the one with UnhandledExceptionEventArgs.

I created a small test project and run your code, everything works as expected (VS2015 Community, AnyCpu/x64, .NET 4.0)

EDIT 1:
Now I think I get it... Your problem is, that if you run your exception code in Form.OnLoad that Visual Studio 'breaks' for you and shows you the unhandled-exception window... Thats fine. Press F5 to continue and your exception handler should be called...

As far as I remember you can change this behavior under Debug -> Windows -> Exception settings

EDIT 2:
Or could it be this? https://stackoverflow.com/a/1583427/8400446

Michael
  • 1,931
  • 2
  • 8
  • 22
  • Michael I have been able to refine my problem, perhaps you'd be interested to see what I was able to deduce? https://stackoverflow.com/questions/45534142/exception-raised-by-timer-elapsed-not-caught-by-attempted-global-exception-event – tgabb Aug 06 '17 at 16:30