6

I'm trying to do this:

I'm creating another form, which in it's FormClosed method throws an exception, that should be caught by the main form.

Main Form:

try
    {
        frmOptions frm  = new frmOptions();
        frm.ShowDialog();                        
    }
catch(Exception)
    {
        MessageBox.Show("Exception caught.");
    }

frmOptions:

private void frmOptions_FormClosed(object sender, FormClosedEventArgs e)
{
    throw new Exception();
}

The debugger stops on the exception with this message:

Exception was unhandled by user code

Why? I'm catching the exception in the owner of the object that created it. Anybody has an idea?

mileski
  • 158
  • 2
  • 11
  • 1
    Please don't put C# in the title. That is what the tags are for. –  Dec 05 '11 at 05:23
  • I don't get the issue you describe. I thought the issue did exist because the frmOptions was running on a different thread but apparently that's not the case. I am able to catch the exception w/o problems. I tested targeting .NET 2 and 4. – Icarus Dec 05 '11 at 05:29
  • @Icarus: Goto Debugger -> Exceptions -> Reset all. Then try again, and you'll get the unhnadled exception by user code. – mileski Dec 05 '11 at 05:33
  • @makmiler: Did that. Same non-issue. – Icarus Dec 05 '11 at 05:57
  • @Icarus well, I use VS 2010 and .net 4, so it happens. Others got the same error. Why you are not seeing the message, I really don't know. – mileski Dec 05 '11 at 13:51

4 Answers4

3

you can handle all exception in your project from program.cs

static class Program
        {

            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;

                Application.ThreadException += Application_ThreadException;
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);         
                Application.Run(new MainMDI());              
            }
            static void Application_ThreadException(Object sender, ThreadExceptionEventArgs e)
            {
                MessageBox.Show(e.Exception.Message, "Application.ThreadException");
            }

            static void AppDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e)
            {
                MessageBox.Show(((Exception)e.ExceptionObject).Message, "AppDomain.UnhandledException");
            }
        }
Nighil
  • 4,099
  • 7
  • 30
  • 56
2

I don't think this can work, the new form is not running in the context of your code above, it is only being launched by it. If you check the stacktrace for the exception thrown you shouldn't see the code above in it, so it can't catch the exception.

Update: I just created a test project & tried it. The stacktrace knows nothing about the original form. If you want to catch unhandled exceptions you may want to check out this question Unhandled Exception Handler in .NET 1.1

Community
  • 1
  • 1
Glenn Slaven
  • 33,720
  • 26
  • 113
  • 165
  • 1
    What do you mean by "it is only being launched by it"? The object is created in the object space of the form that created it. If I turn the "do not stop on unhandled exceptions", the exception is being caught in the try/catch block of the main form. But that is also a "managed" exception handling. The question is why the debugger sees it as unhnadled? – mileski Dec 05 '11 at 04:46
  • As Renato mentioned in a comment on their answer, the new form runs in a separate UI thread, even if it's launched modally. An error in frmOptions does not have any reference to the launching form in its stacktrace – Glenn Slaven Dec 05 '11 at 05:09
  • then you will get ThreadException, and not an unhandled user code exception. I don't believe that's the case, because, if you turn off the debugger-Exceptions-Stop on unhandled user code, the try/catch block of the main form actually catches the exception. – mileski Dec 05 '11 at 14:00
  • @makmiler I can't make it do that, the exception doesn't go anywhere near the calling form – Glenn Slaven Dec 05 '11 at 22:02
2

You'll be able to do this as follows:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2(this);
        form2.Show();
    }

    public void HandleForm2Exception(Exception ex)
    {
        MessageBox.Show("EXCEPTION HAPPENED!");
    }
}

and on Form2.cs

public partial class Form2 : Form
{
    private Form1 form1;

    public Form2(Form1 form1) : this()
    {
        this.form1 = form1;
    }

    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        try
        {
            throw new Exception();
        }
        catch (Exception ex)
        {
            if(this.form1 != null)
                this.form1.HandleForm2Exception(ex);
        }
    }
}
Renato Gama
  • 16,431
  • 12
  • 58
  • 92
  • yes, nice trick, but no. That's not the issue here. Please read my question again :) – mileski Dec 05 '11 at 04:54
  • 1
    makmiler, happens that your second form is running within a different ui thread context, thats why you wont be able to catch this exception directly, and thats why Glenn Slaven answers makes perfect sense. @this.__curious_geek, why wouldn't you recommend it? – Renato Gama Dec 05 '11 at 04:59
  • @Renato Gama, if that's the case, then why if you turn off the debugger-Exceptions-Stop on unhandled user code, the try/catch block of the main form actually catches the exception? – mileski Dec 05 '11 at 13:49
  • @makmiler, I couldn't reproduce your step! what exactly did you do? – Renato Gama Dec 05 '11 at 18:56
1

Why are you trying throw an exception from one form to another? "Don't throw new Exception()"

If you are trying to let the main form know that the options form is closed you could just have a flag on the main form which is set from the options form.

Hugo
  • 710
  • 1
  • 10
  • 19
  • I know that. I'm asking why the debugger stops on the exception as unhandled user code, when, in fact, the creation of the form IS in a try/catch block, and if you turn the option to stop the debugger on such user code, the exception will be caught in the end. – mileski Dec 05 '11 at 14:09