Bug in exception handling

G

Guest

Why is it so difficult to report bugs to Microsoft? I have a documented bug
and an small test example. I don't really see why I should have to pay to
tell them about it...

Anyway, the following code exhibits the bug. If it is built and run from
Visual Studio.NET 2003 in debug mode it works correctly as expected.
However, if built in Release mode it fails with an "uncaught exception"
error, although the exception does have a valid catch handler.

To repeat, create a new Windows Forms application and put the following code
into Form1.cs.

----

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Main: Caught exception: ");
}
}

private void button1_Click(object sender, System.EventArgs e)
{
try
{
Foo();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "button1_Click: Caught exception: ");
throw;
}
}

void Foo()
{
throw new Exception("Exception thrown from Foo()");
}
 
M

Morten Wennevik

Hi David,

I can't say if it is fixed in service pack 1, but the code runs fine in Framework 2.0 both debug and release.
 
W

Wiktor Zychla

Application.Run(new Form1());

it is rather by design of the WinForms that the exceptions thrown outside
the Application.Run are not caught by try-catch but by the thread's global
exception handler set by Application.ThreadException.

so, instead of

try
{
Application.Run(...)
}
catch() {...}

use

Application.ThreadException += new ThreadExceptionEventHandler(
MyExceptionHandler );
Application.Run(...);

....

public static void MyExceptionHandler( object sender,
ThreadExceptionEventArgs e )

{

Exception ex = e.Exception;

// do something with the exception but you are unlikely to resume the
application

Application.Exit();

}



regards,

Wiktor Zychla
 
G

Guest

Hi David,

Why is it so difficult to report bugs to Microsoft? I have a documented bug
and an small test example. I don't really see why I should have to pay to
tell them about it...

Yeah!
That seems to be real problem in M$.
I work with VS 2002 and .NET Framework 1.0, and only SP 3 for this
framework repairs something for real.

It seems that Windows application doesn't like exceptions in
event handling.
Your sample runs fine in VS 2002 Release mode... but it crashes
on direct execution.

Cheers

Marcin
Anyway, the following code exhibits the bug. If it is built and run from
Visual Studio.NET 2003 in debug mode it works correctly as expected.
However, if built in Release mode it fails with an "uncaught exception"
error, although the exception does have a valid catch handler.

To repeat, create a new Windows Forms application and put the following code
into Form1.cs.

----

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Main: Caught exception: ");
}
}

private void button1_Click(object sender, System.EventArgs e)
{
try
{
Foo();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "button1_Click: Caught exception: ");
throw;
}
}

void Foo()
{
throw new Exception("Exception thrown from Foo()");
}
 
M

Morten Wennevik

Interesting, this works applications run outside Visual Studio, but Visual Studio 2005 does not like it at all and claims the throw before the application exception is unhandled.
 
W

Wiktor Zychla

Interesting, this works applications run outside Visual Studio, but Visual
Studio 2005 does not like it at all and claims the throw before the
application exception is unhandled.

wrap the code with Application.ThreadException += with a try-catch.

this way the code will work standalone (because the ThreadException will
catch the outer exception) and should also work from within the VS.NET
(because the try-catch will catch the outer exception).

try
{
Application.ThreadException += ...
Application.Run(...);
}
catch( Exception ex ) {...}

it works for me in vs2003 at least.

Wiktor ZYchla
 
M

Morten Wennevik

Studio 2005 does not like it at all and claims the throw before the
application exception is unhandled.

wrap the code with Application.ThreadException += with a try-catch.

this way the code will work standalone (because the ThreadException will
catch the outer exception) and should also work from within the VS.NET
(because the try-catch will catch the outer exception).

try
{
Application.ThreadException += ...
Application.Run(...);
}
catch( Exception ex ) {...}

it works for me in vs2003 at least.

Wiktor ZYchla

This also works in 2005. Very handy piece of code. Thanks :)
 
J

Jay B. Harlow [MVP - Outlook]

David,
Your try/catch in your Main is only catching exceptions that the constructor
of Form1 raises!

The exception that your button1_Click raises is not handled, VS.NET handles
the exception for you, so as to allow you to debug the problem with your
program.

You need to handle the Application.ThreadException event in your Main to
catch unhandled that button1_Click raises.

Depending on the type of application you are creating, .NET has three
different global exception handlers.

For ASP.NET look at:
System.Web.HttpApplication.Error event
Normally placed in your Global.asax file.

For console applications look at:
System.AppDomain.UnhandledException event
Use add handler in your Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use add handler in your Main.

It can be beneficial to combine the above global handlers in your app, as
well as wrap your Sub Main in a try catch itself.

There is an article in the June 2004 MSDN Magazine that shows how to
implement the global exception handling in .NET that explains why & when you
use multiple of the above handlers...

http://msdn.microsoft.com/msdnmag/issues/04/06/NET/default.aspx

For example: In my Windows Forms apps I would have a handler attached to the
Application.ThreadException event, plus a Try/Catch in my Main. The
Try/Catch in Main only catches exceptions if the constructor of the MainForm
raises an exception, the Application.ThreadException handler will catch all
uncaught exceptions from any form/control event handlers.

Note David has some excellent comments on argument validation to your class
libraries. Especially if those class libraries are going to be used outside
of your current solution.

Hope this helps
Jay



David B said:
Why is it so difficult to report bugs to Microsoft? I have a documented
bug
and an small test example. I don't really see why I should have to pay to
tell them about it...

Anyway, the following code exhibits the bug. If it is built and run from
Visual Studio.NET 2003 in debug mode it works correctly as expected.
However, if built in Release mode it fails with an "uncaught exception"
error, although the exception does have a valid catch handler.

To repeat, create a new Windows Forms application and put the following
code
into Form1.cs.

----

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Main: Caught exception: ");
}
}

private void button1_Click(object sender, System.EventArgs e)
{
try
{
Foo();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "button1_Click: Caught exception: ");
throw;
}
}

void Foo()
{
throw new Exception("Exception thrown from Foo()");
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top