How to force the program to continue after unhandled exceptiondetection

N

nano2k

Hi

For my winforms app (.net 2.0) I have defined a general exception
handler:

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

//....

void Application_ThreadException(object sender,
System.Threading.ThreadExceptionEventArgs e) {
//show a decent message
}

Ok, the thing is that when in debugging mode and an unhandled
exception occurs, the exception helper pops up.
On this point, I'm stucked. Can't get rid of exception helper, even if
I want the exception to be handled by the general exception handler I
defined.
I have played with exception settings (CTRL-D, E), but no luck.
I really need to keep this design, so I need to be able to let the
program to continue execution.
How to do this?

Thanks.
 
P

Peter Duniho

[...]
On this point, I'm stucked. Can't get rid of exception helper, even if
I want the exception to be handled by the general exception handler I
defined.

There's a fundamental mistake in your assumptions. That is, you have not
actually defined a "general exception handler".

You've defined a handler for the ThreadException _event_, but that's
entirely different. It doesn't handle an exception, it handles the event
that's raised when an exception _isn't_ handled.

If you want the exception to be handled, you need to handle it. With a
try/catch block, not an event handler.

Pete
 
N

nano2k

[...]
On this point, I'm stucked. Can't get rid of exception helper, even if
I want the exception to be handled by the general exception handler I
defined.

There's a fundamental mistake in your assumptions.  That is, you have not  
actually defined a "general exception handler".

You've defined a handler for the ThreadException _event_, but that's  
entirely different.  It doesn't handle an exception, it handles the event  
that's raised when an exception _isn't_ handled.

If you want the exception to be handled, you need to handle it.  With a  
try/catch block, not an event handler.

Pete

You're right, I made a mistake. I handled an event, that's right.
But the question remains. I want to get rid of exception helper and
let this event handler deal with the exception.
I have tons of places where exception handling is necessary and the
handler looks like: "If an unhadled exception raises, than simply
display its message and continue running!". Why should I write _the
same_ code each time?
Of course, there are also many many cases where I need to handle
specific types of exceptions and take the appropriate measures. I'm
not talking about these ones.
But in modern exception handling approach, implementing a general
exception catching mechanism is a _must_.
The only problem is that I get stucked in VSNET2005 when such an
"unhandled" exception occurs.
 
J

Jeroen

Nano2k,

Press 'Continue' (a green arrow button pointing rightward, from the
top of my had) in the Visual Studio debugger, and then the code will
go into your event handler when running from Visual Studio as well.

Let us know if that solved your problem.

Regards,
Jeroen
 
N

nano2k

Nano2k,

Press 'Continue' (a green arrow button pointing rightward, from the
top of my had) in the Visual Studio debugger, and then the code will
go into your event handler when running from Visual Studio as well.

Let us know if that solved your problem.

Regards,
Jeroen

Sorry, doesn't work...
 
P

Peter Duniho

You're right, I made a mistake. I handled an event, that's right.
But the question remains. I want to get rid of exception helper and
let this event handler deal with the exception.

While I don't know what an "exception helper" is, and "deal with" is
ambiguous. But assuming you mean for the event handler to actually trap
the exception, the short answer is that you can't do that. It doesn't
trap exceptions. It's entirely unrelated to the exception except that it
gets raised by the .NET exception handler when an exception is thrown in
the main GUI thread.

It's not an exception handler, and it will never be one.
I have tons of places where exception handling is necessary and the
handler looks like: "If an unhadled exception raises, than simply
display its message and continue running!". Why should I write _the
same_ code each time?

Because you want to handle the exception?
Of course, there are also many many cases where I need to handle
specific types of exceptions and take the appropriate measures. I'm
not talking about these ones.
But in modern exception handling approach, implementing a general
exception catching mechanism is a _must_.

Well, obviously it's not a "must" since plenty of modern frameworks that
use exceptions don't provide a way to implement a general catching
mechanism.
The only problem is that I get stucked in VSNET2005 when such an
"unhandled" exception occurs.

I'm not aware of any setting in VS2005 that will allow the debugger to
ignore exceptions that would be handled by the .NET GUI thread exception
handler. That doesn't mean the setting doesn't exist, it just means I
don't know where it is if it does.

Regardless, it's not a good idea for you to have a dependency on this
general purpose exception handling. Exceptions are exceptional cases. If
they are being thrown regularly enough that you find it overly
time-consuming to add exception handlers everywhere that they could come
up, then either your code is throwing too many exceptions or you are not
handling them in the way that you should.

An exception represents an error. Either you have a good way to recover
from an error or you don't. If you do, then the exception handler that
will allow you to recover from an error belongs with the code where the
error is created. That means writing exception handling code (i.e. using
try/catch). If you don't have a good way to recover from an error, then
no matter where you put whatever code reacts to the error, it's still
wrong.

I'm sorry your frustrated by this, but I believe that if what you're
trying to do was a good way to design a program, you wouldn't be fighting
the tools trying to do it.

Pete
 
P

Peter Duniho

Sorry, doesn't work...

What doesn't work about that? Are you saying that even when you've
subscribed to the ThreadException event, that when an exception occurs
your application cannot be continued?

If not, then what are you saying?

And in either case, especially because of the apparent confusion in what
you're trying to describe, it would be very helpful if you would provide a
concise-but-complete code example that demonstrates the problem. Describe
very clearly what it is you expect to be able to do with the example, and
what you observe it doing instead.

Pete
 
P

Peter Duniho

[...]
The only problem is that I get stucked in VSNET2005 when such an
"unhandled" exception occurs.

I'm not aware of any setting in VS2005 that will allow the debugger to
ignore exceptions that would be handled by the .NET GUI thread exception
handler. That doesn't mean the setting doesn't exist, it just means I
don't know where it is if it does.

I take that back. A few minutes of looking revealed to me that in the
Debug/Exceptions... menu, if you uncheck the "User-unhandled" column for
an exception, then as long as that exception is handled _somewhere_ (for
example, in the Application class's default exception handler, which is
active when you subscribe to the ThreadException event), the debugger
won't interrupt the program.

I still assert that if your application is dependent on this sort of
thing, there's something wrong with the design, and I also don't
understand why you aren't able to continue after the exception when it's
being handled (that works fine for me). But it appears to me that you can
get VS to do exactly what you want, however inappropriate it might be to
do so.

Pete
 
N

nano2k

Hi Peter.

Let's say my client app calls a webservice.
The webservice is pretty much used by the client app. That is, the
application performs many accesses to the webservice because it
maintains a database behind the webservice.
For this, the webservice implements many different methods callable
from the client app.
Now, it's not hard to imagine that each webservice call _could_ fail
because of network failures, etc. BUT, the message will still be the
same. Like: "Oops, the call failed!" or: "Unexpected error". It is a
huge and unnecessary work for me to handle each webservice call by
copy/pasting the same code to handle the exceptions.
Not to mention what happens if I want to change the error message to:
"Oh my God! An unexpected error!". Or if you want to translate the
message...
Well, getting serious now. Such a general error handling system is
very useful in these situations. Note: I understand that the handler
is only an _event_ handler, not an _exception_ handler.
All this talking is to make you understand that handling _each_
potential exception could be itself a design problem leading at least
to inconsistency in treating unexpected exceptions. To put it in
another way, handling _all_ possible exception types that might raise
from each piece of code could rather be a design problem in some
situations. Not in all situations. But some of them.

Now, if I put my trust in handling Application.ThreadException event,
even if it works flawlessly, VS Studio 2005 will always pop-up the
exception helper window (this is good and normal), but the bad thing
is that this exception helper won't go away no matter what I try. An
also, the execution pointer will not advance. It detects an unhandled
exception, which, yeah!, it's true!, ignoring that the exception is,
or coudl be, somehow, handled in the handler associated with the
Application.ThreadException event.

Running the application without attaching the debugger (e.g. CTRL-F5),
all works fine. The exception is raised, but the general error message
appears gracefully. I can dismiss the message and the application is
perfectly recovered.

Now, a little bity of code:
I have a base form and a bunch of forms derived from this base form.
All these forms work inside a MDI Parent form as MDI childs. ONLY ONE
MDI child is shown at a time. Each time a new form is shown (based on
user selection through a menu), the current form is closed and
disposed. Then, the new one is created and shown.
The base form looks like this:

public class BaseForm : Form {
public BaseForm() {
Application.ThreadException +=
new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}
//...few different members...
protected override void OnClosed(EventArgs e) {
Application.ThreadException -=
new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
base.OnClosed(e);
}
void Application_ThreadException(object sender,
System.Threading.ThreadExceptionEventArgs e) {
Utils.ShowGeneralErrorMessage(this, e.Exception);
}
}

Now, let's imagine we have a form that is derived from BaseForm and
has several buttons. Each button produces one or more webservice
methods invocations:

public partial class FirstForm : BaseForm {
private void button1_Click(object sender, EventArgs e) {
//some code
//followed by webservice call(s)
}
private void button2_Click(...) {
//simmilar to button1
}

//other buttons PLUS other calls to the webservice

}

Now, why should I "decorate" each code in Click event handlers with
something like this?:

private void button1_Click(object sender, EventArgs e) {
try {
//call webservice
}
catch (SoapException ex) {
Message.Show(ex.Message);
}
}

Just because the exception helper won't let me? It could be an answer,
but could I disable this behavior?
Note: I have already played fair enough with Debug/Exceptions
settings. Can't make it work as I expected.
I didn't assume I didn't make a design mistake when I expected this
behavior. But how could I solve this issue?

Thanks again.



[...]
The only problem is that I get stucked in VSNET2005 when such an
"unhandled" exception occurs.
I'm not aware of any setting in VS2005 that will allow the debugger to  
ignore exceptions that would be handled by the .NET GUI thread exception 
handler.  That doesn't mean the setting doesn't exist, it just means I 
don't know where it is if it does.

I take that back.  A few minutes of looking revealed to me that in the  
Debug/Exceptions... menu, if you uncheck the "User-unhandled" column for  
an exception, then as long as that exception is handled _somewhere_ (for  
example, in the Application class's default exception handler, which is  
active when you subscribe to the ThreadException event), the debugger  
won't interrupt the program.

I still assert that if your application is dependent on this sort of  
thing, there's something wrong with the design, and I also don't  
understand why you aren't able to continue after the exception when it's  
being handled (that works fine for me).  But it appears to me that you can  
get VS to do exactly what you want, however inappropriate it might be to  
do so.

Pete
 
P

Peter Duniho

[...]
Now, if I put my trust in handling Application.ThreadException event,
even if it works flawlessly, VS Studio 2005 will always pop-up the
exception helper window (this is good and normal), but the bad thing
is that this exception helper won't go away no matter what I try.

Then I take it you have not tried the solution I posted in my previous
message.

I disagree with your analysis of "why" you need to handle exceptions with
the ThreadException event, but the fact is that even doing so it's not
difficult at all to get the debugger to ignore exceptions that you've
handled that way.

If you are having some trouble getting that technique to work, you should
explain better what you're doing and what's not working as you expect.

Pete
 
N

nano2k

Pete,
First of all, thanks for your patience.
You may repro the behavior with VSNET 2005 like this:
1. Create a winform app.
2. Put a button on the form.

3. Add this handler for form's Load event:
private void Form1_Load (object sender, EventArgs e) {
Application.ThreadException +=
new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}
4. And for FormClosed event:
private void Form1_FormClosed (object sender,
FormClosedEventArgs e) {
Application.ThreadException -=
new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}
5. Then, implement the ThreadException handler like this:
void Application_ThreadException (object sender,
System.Threading.ThreadExceptionEventArgs e) {
MessageBox.Show(e.Exception.Message); //show simple
message
}
6. Simmulate an unhandled exception:
private void button1_Click (object sender, EventArgs e) {
//simmulate an unhandled exception
throw new ApplicationException("Ooops! Unhandled
exception!");
}

7. Normally, if no event handler was defined for
Application.ThreadException event, the application would crash when
the button is clicked.
Run the application without debugger: CTRL-F5. Click the button: the
error message appears. Dismiss the message. The application is running
normally.

8. Run the application with the debugger attached. Click the button.
The debugger detects the unhandled exception and stops the program at
the following line showing the exception helper:

throw new ApplicationException("Ooops! Unhandled exception!");

Cool, until now, it's perfect! Now, try to continue the execution of
the program. No chance! No matter what settings you change in Debug/
Exceptions section.
It is normal to be able to continue the execution, as the application
WILL ACTUALLY CONTINUE ITS EXECUTION when running in production
environment.

Now, if there's a design problem, I wonder what good is for to handle
the Application.ThreadException event (I mean when in debug mode).
Anyway, even if it's a design problem (which I don't think), can I
make the exception helper let me be?

Thanks.


[...]
Now, if I put my trust in handling Application.ThreadException event,
even if it works flawlessly, VS Studio 2005 will always pop-up the
exception helper window (this is good and normal), but the bad thing
is that this exception helper won't go away no matter what I try.

Then I take it you have not tried the solution I posted in my previous  
message.

I disagree with your analysis of "why" you need to handle exceptions with  
the ThreadException event, but the fact is that even doing so it's not  
difficult at all to get the debugger to ignore exceptions that you've  
handled that way.

If you are having some trouble getting that technique to work, you should  
explain better what you're doing and what's not working as you expect.

Pete
 
P

Peter Duniho

Pete,
First of all, thanks for your patience.
You may repro the behavior with VSNET 2005 like this:
1. Create a winform app.
2. Put a button on the form.

3. Add this handler for form's Load event:
private void Form1_Load (object sender, EventArgs e) {
Application.ThreadException +=
new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
}

From the MSDN documentation for the Application.ThreadException event, in
a clearly emphasized "Note:" box:

"To use this event, you must attach a
handler before you call Application.Run"

http://msdn2.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx
[...]
7. Normally, if no event handler was defined for
Application.ThreadException event, the application would crash when
the button is clicked.
Run the application without debugger: CTRL-F5. Click the button: the
error message appears. Dismiss the message. The application is running
normally.

I'm surprised you even got it to work at all using the code you posted.
8. Run the application with the debugger attached. Click the button.
The debugger detects the unhandled exception and stops the program at
the following line showing the exception helper:

throw new ApplicationException("Ooops! Unhandled exception!");

Cool, until now, it's perfect! Now, try to continue the execution of
the program. No chance! No matter what settings you change in Debug/
Exceptions section.

I am unable to reproduce your problem, at least when I used the
ThreadException event correctly. I haven't bothered to try using it
wrong, but I can believe that there might be a difference.

When I set up a ThreadException handler correctly, by subscribing the
handler before I call Application.Run(), then once the debugger detects
the exception and interrupts the program, I can simply continue execution
and the program continues running just as it would have had the debugger
not been present.

If you can reproduce the problem you're describing when you've used
ThreadException correctly, _then_ there's something for you to be
concerned with. But in that case, it means that there's something about
your installation that is broken.

Normally it would work just as you desire (and as I noted, you can even
disable interrupting execution for handled exceptions altogether...the
default is for the debugger to break any time an exception isn't handled
by your own code, but you can set it for other behaviors, including
breaking only when the exception is unhandled altogether, or breaking
whether or not the exception is handled anywhere).

Pete
 
N

nano2k

Pete,
First of all, thanks for your patience.
You may repro the behavior with VSNET 2005 like this:
1. Create a winform app.
2. Put a button on the form.
3. Add this handler for form's Load event:
        private void Form1_Load (object sender, EventArgs e) {
            Application.ThreadException +=
                new
System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
        }

 From the MSDN documentation for the Application.ThreadException event, in  
a clearly emphasized "Note:" box:

     "To use this event, you must attach a
     handler before you call Application.Run"

http://msdn2.microsoft.com/en-us/library/system.windows.forms.applica...
[...]
7. Normally, if no event handler was defined for
Application.ThreadException event, the application would crash when
the button is clicked.
Run the application without debugger: CTRL-F5. Click the button: the
error message appears. Dismiss the message. The application is running
normally.

I'm surprised you even got it to work at all using the code you posted.
8. Run the application with the debugger attached. Click the button.
The debugger detects the unhandled exception and stops the program at
the following line showing the exception helper:
throw new ApplicationException("Ooops! Unhandled exception!");
Cool, until now, it's perfect! Now, try to continue the execution of
the program. No chance! No matter what settings you change in Debug/
Exceptions section.

I am unable to reproduce your problem, at least when I used the  
ThreadException event correctly.  I haven't bothered to try using it  
wrong, but I can believe that there might be a difference.

When I set up a ThreadException handler correctly, by subscribing the  
handler before I call Application.Run(), then once the debugger detects  
the exception and interrupts the program, I can simply continue execution  
and the program continues running just as it would have had the debugger  
not been present.

If you can reproduce the problem you're describing when you've used  
ThreadException correctly, _then_ there's something for you to be  
concerned with.  But in that case, it means that there's something about 
your installation that is broken.

Normally it would work just as you desire (and as I noted, you can even  
disable interrupting execution for handled exceptions altogether...the  
default is for the debugger to break any time an exception isn't handled  
by your own code, but you can set it for other behaviors, including  
breaking only when the exception is unhandled altogether, or breaking  
whether or not the exception is handled anywhere).

Pete

Pete, you're the one!
Handling the event _before_ calling Application.Run() worked!
Indeed, I was using the wrong way this handler.
Anyway, maybe this topic will help someone else.

Thanks again.
 

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