Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control.Invoke unwraps the outer exception and propagates the inner exception instead

The MessageBox.Show call below shows "Inner". Is this a bug?

private void Throw()
{
    Invoke(new Action(() =>
    {
        throw new Exception("Outer", new Exception("Inner"));
    }));
}

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        Throw();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message); // Shows "Inner"
    }
}
like image 528
Juan Avatar asked Jan 20 '15 20:01

Juan


1 Answers

I had a look at the reference source for System.Windows.Forms.Control, and the code that deals with Invoke looks like this:

try {
    InvokeMarshaledCallback(current);
}
catch (Exception t) {
    current.exception = t.GetBaseException();
}

GetBaseException:

public virtual Exception GetBaseException() 
{
    Exception inner = InnerException;
    Exception back = this;

    while (inner != null) {
        back = inner;
        inner = inner.InnerException;
    }

    return back;
}

So apparently it's like this by design. The comments in the source offer no explanation as to why they do this.

EDIT: Some site that is now gone claims this comment came from a guy at Microsoft:

Based on the winform comfirmation in the record, our analysis is correct of the root cause and this behavior is intended. The reason was to prevent the user from seeing too much of the Windows.Forms internal mechanisms. This is because the winform's default error dialog also leverages Application.ThreadException to show the exception details. .Net Winform team trims the other exceptions information so that the default error dialog will not display all the details to the end user.

Also, some MSFTs have sugguested to change this behavior. However, .Net Winform team thinks that changing the exception to throw is a breaking change and for this reason WinForms will keep sending the innermost exception to the Application.ThreadException handler.

like image 61
Chris Avatar answered Oct 01 '22 16:10

Chris