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