473,503 Members | 1,625 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Exception management question...

I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose of
handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions, with
inner exceptions, etc.) that help to describe and clarify any errors that
occur. This way, when the nested exceptions are finally handled within the
high-level tasks, there will be sufficient information to describe the
problem.

Does this sound like the correct approach? Are there any good MSDN articles
on this subject?
Nov 16 '05 #1
44 4158
Greetings,
Eric Gunnerson wrote a few valuable articles on Exceptions on MSDN.
See
http://msdn.microsoft.com/library/de...rp08162001.asp

"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...
I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions, with inner exceptions, etc.) that help to describe and clarify any errors that
occur. This way, when the nested exceptions are finally handled within the high-level tasks, there will be sufficient information to describe the
problem.

Does this sound like the correct approach? Are there any good MSDN articles on this subject?

Nov 16 '05 #2
Microsoft's Patterns & Practices contains an Exception Management
Architecture Guide:

http://msdn.microsoft.com/library/de...ceptdotnet.asp

Regards,
Joakim
craig wrote:
I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose of
handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions, with
inner exceptions, etc.) that help to describe and clarify any errors that
occur. This way, when the nested exceptions are finally handled within the
high-level tasks, there will be sufficient information to describe the
problem.

Does this sound like the correct approach? Are there any good MSDN articles
on this subject?

Nov 16 '05 #3
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
Disagree: In an effort to avoid duplicate code (try/catch/log exception) I
tend to leave exception logging to my global exception handlers, instead I
use try/finally & using statements to ensure any resources are cleaned up.
2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with Agree: I will use a try/catch when there is something specific to do, such
as a retry on FileNotFound, or throwing context sensitive exceptions. IMHO
logging the exception is not specific enough...
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 AddHandler in your Sub Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use AddHandler in your Sub 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/is...T/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.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with inner exceptions, etc.) that help to describe and clarify any errors
that occur. This way, when the nested exceptions are finally handled
within the high-level tasks, there will be sufficient information to
describe the problem.

Does this sound like the correct approach? Are there any good MSDN
articles on this subject?

Nov 16 '05 #4
In case you are thinking about implementing an exception handling framework,
you could have a look at
http://www.codeproject.com/script/ar...?userid=450027

Jeff has written some really nice libraries (one for WinForm and one for
WebForm)

- José

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> a écrit dans le
message de news: %2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that


Disagree: In an effort to avoid duplicate code (try/catch/log exception) I
tend to leave exception logging to my global exception handlers, instead I
use try/finally & using statements to ensure any resources are cleaned up.
2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with

Agree: I will use a try/catch when there is something specific to do, such
as a retry on FileNotFound, or throwing context sensitive exceptions. IMHO
logging the exception is not specific enough...
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 AddHandler in your Sub Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use AddHandler in your Sub 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/is...T/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.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...
I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with inner exceptions, etc.) that help to describe and clarify any errors
that occur. This way, when the nested exceptions are finally handled
within the high-level tasks, there will be sufficient information to
describe the problem.

Does this sound like the correct approach? Are there any good MSDN
articles on this subject?


Nov 16 '05 #5
This is a great article. I have used it when I needed to add new exception
classes of my own.

"Marek" <ma********@hotmail.com> wrote in message
news:%2******************@TK2MSFTNGP09.phx.gbl...
Greetings,
Eric Gunnerson wrote a few valuable articles on Exceptions on MSDN.
See
http://msdn.microsoft.com/library/de...rp08162001.asp

"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...
I am wondering if there are some best practices for determining a
strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose

of
handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,

with
inner exceptions, etc.) that help to describe and clarify any errors that
occur. This way, when the nested exceptions are finally handled within

the
high-level tasks, there will be sufficient information to describe the
problem.

Does this sound like the correct approach? Are there any good MSDN

articles
on this subject?


Nov 16 '05 #6
Thanks! Just what I was looking for.

"Joakim Karlsson" <jk*******@NOSPAMjkarlsson.com> wrote in message
news:%2******************@TK2MSFTNGP12.phx.gbl...
Microsoft's Patterns & Practices contains an Exception Management
Architecture Guide:

http://msdn.microsoft.com/library/de...ceptdotnet.asp

Regards,
Joakim
craig wrote:
I am wondering if there are some best practices for determining a
strategy for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with inner exceptions, etc.) that help to describe and clarify any errors
that occur. This way, when the nested exceptions are finally handled
within the high-level tasks, there will be sufficient information to
describe the problem.

Does this sound like the correct approach? Are there any good MSDN
articles on this subject?

Nov 16 '05 #7
Quite a bit to chew on here. I wonder how what you are describing here
squares up with the approach outlined in the Exception Management
Architecture Guide listed in Joakim's post.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that


Disagree: In an effort to avoid duplicate code (try/catch/log exception) I
tend to leave exception logging to my global exception handlers, instead I
use try/finally & using statements to ensure any resources are cleaned up.
2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with

Agree: I will use a try/catch when there is something specific to do, such
as a retry on FileNotFound, or throwing context sensitive exceptions. IMHO
logging the exception is not specific enough...
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 AddHandler in your Sub Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use AddHandler in your Sub 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/is...T/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.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...
I am wondering if there are some best practices for determining a strategy
for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions and
building a set of nested exceptions (exceptions with inner exceptions,
with inner exceptions, etc.) that help to describe and clarify any errors
that occur. This way, when the nested exceptions are finally handled
within the high-level tasks, there will be sufficient information to
describe the problem.

Does this sound like the correct approach? Are there any good MSDN
articles on this subject?


Nov 16 '05 #8

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that


Disagree: In an effort to avoid duplicate code (try/catch/log exception) I
tend to leave exception logging to my global exception handlers, instead I
use try/finally & using statements to ensure any resources are cleaned up.


There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.

Nov 16 '05 #9
Craig,
This article might explain better what I was stating:
http://msdn.microsoft.com/msdnmag/is...T/default.aspx
Hope this helps
Jay

"craig" <e@mail.com> wrote in message
news:el****************@TK2MSFTNGP10.phx.gbl... Quite a bit to chew on here. I wonder how what you are describing here
squares up with the approach outlined in the Exception Management
Architecture Guide listed in Joakim's post.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that


Disagree: In an effort to avoid duplicate code (try/catch/log exception)
I tend to leave exception logging to my global exception handlers,
instead I use try/finally & using statements to ensure any resources are
cleaned up.
2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions
and building a set of nested exceptions (exceptions with inner
exceptions, with

Agree: I will use a try/catch when there is something specific to do,
such as a retry on FileNotFound, or throwing context sensitive
exceptions. IMHO logging the exception is not specific enough...
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 AddHandler in your Sub Main.

For Windows Forms look at:
System.Windows.Forms.Application.ThreadException event
Use AddHandler in your Sub 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/is...T/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.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:OU****************@TK2MSFTNGP15.phx.gbl...
I am wondering if there are some best practices for determining a
strategy for using try/catch blocks within an application.

My current thoughts are:

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that
occur (log the exception, display a message box, etc.).

2. Low-level operations that are used to carry out the high level tasks
should make use of try/catch blocks where necessary, not for the purpose
of handling the exceptions, but for the purpose of raising exceptions
and building a set of nested exceptions (exceptions with inner
exceptions, with inner exceptions, etc.) that help to describe and
clarify any errors that occur. This way, when the nested exceptions are
finally handled within the high-level tasks, there will be sufficient
information to describe the problem.

Does this sound like the correct approach? Are there any good MSDN
articles on this subject?



Nov 16 '05 #10
David,
There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions. Agree: However its not just my application, If you haven't reviewed the
article you might want to:
http://msdn.microsoft.com/msdnmag/is...T/default.aspx

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:eX****************@TK2MSFTNGP12.phx.gbl...
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.
1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that


Disagree: In an effort to avoid duplicate code (try/catch/log exception)
I tend to leave exception logging to my global exception handlers,
instead I use try/finally & using statements to ensure any resources are
cleaned up.


There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.

Nov 16 '05 #11
Jay,

I've read that article, as well as numerous others on exceptions. I disagree
with using the UE as your primary mechanism for reporting or dealing with
exceptions.

Here's a simple scenario where subscribing to the UE as your main handler
wont work...a launcher creates a 2nd appdomain and uses that to run your
windows form in...the windows form does not know that it is running in a 2nd
appdomain. It subscribes to the UE. However, in the 1.x runtime only
handlers in the default appdomain actually get the nofication and you wont
even get an error notification that the subcription attempt is a no-op; and
who knows what the launcher actually does with it?... probably be the wrong
thing anyway...result is a UE gets dropped.

Let's say that the launcher does subscribe to the UE and you want that to be
your primary handler. Now when a UE happens in the 2nd appdomain it gets
serialized across the appdomain boundary before it gets handled by the
default appdomain's UE handler. Let's say the exception happens to be a
custom exception type defined by an assembly that is only accessible via the
loading rules in effect in the 2nd appdomain. The result is that another
exception will occur when the runtime tries to deserialize the original
exception type at the appdomain boundary. The result is that you will
actually get a TypeLoadException instead of the original custom exception.

In other words, using the UE as your main mechanism for dealing with
exceptions already wont work in all cases, and as the runtime evolves it is
even less likely to be a viable means of dealing with exceptions, other then
as a last-ditch attempt to notify the user that something bad happened and
leave some trouble-shooting breadcrumbs behind. Bottom line... it may work
well for simple apps but I would not use it in a large, mission critical
app.

Hope this helps, and regards,
Dave

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:ut****************@TK2MSFTNGP10.phx.gbl...
David,
There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.

Agree: However its not just my application, If you haven't reviewed the
article you might want to:
http://msdn.microsoft.com/msdnmag/is...T/default.aspx

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:eX****************@TK2MSFTNGP12.phx.gbl...

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.

1. The code the initiates any high-level user tasks should always be
included in a try/catch block that actually handles any exceptions that

Disagree: In an effort to avoid duplicate code (try/catch/log exception)
I tend to leave exception logging to my global exception handlers,
instead I use try/finally & using statements to ensure any resources are
cleaned up.


There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.


Nov 16 '05 #12
David,
If my app used a launcher, the launcher would be responsible for the UE, so
I really don't see your point.

I guess we will need to agree to disagree.

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:eG****************@TK2MSFTNGP15.phx.gbl...
Jay,

I've read that article, as well as numerous others on exceptions. I
disagree with using the UE as your primary mechanism for reporting or
dealing with exceptions.

Here's a simple scenario where subscribing to the UE as your main handler
wont work...a launcher creates a 2nd appdomain and uses that to run your
windows form in...the windows form does not know that it is running in a
2nd appdomain. It subscribes to the UE. However, in the 1.x runtime only
handlers in the default appdomain actually get the nofication and you wont
even get an error notification that the subcription attempt is a no-op;
and who knows what the launcher actually does with it?... probably be the
wrong thing anyway...result is a UE gets dropped.

Let's say that the launcher does subscribe to the UE and you want that to
be your primary handler. Now when a UE happens in the 2nd appdomain it
gets serialized across the appdomain boundary before it gets handled by
the default appdomain's UE handler. Let's say the exception happens to be
a custom exception type defined by an assembly that is only accessible via
the loading rules in effect in the 2nd appdomain. The result is that
another exception will occur when the runtime tries to deserialize the
original exception type at the appdomain boundary. The result is that you
will actually get a TypeLoadException instead of the original custom
exception.

In other words, using the UE as your main mechanism for dealing with
exceptions already wont work in all cases, and as the runtime evolves it
is even less likely to be a viable means of dealing with exceptions, other
then as a last-ditch attempt to notify the user that something bad
happened and leave some trouble-shooting breadcrumbs behind. Bottom
line... it may work well for simple apps but I would not use it in a
large, mission critical app.

Hope this helps, and regards,
Dave

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:ut****************@TK2MSFTNGP10.phx.gbl...
David,
There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.

Agree: However its not just my application, If you haven't reviewed the
article you might want to:
http://msdn.microsoft.com/msdnmag/is...T/default.aspx

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:eX****************@TK2MSFTNGP12.phx.gbl...

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in
message news:%2******************@TK2MSFTNGP14.phx.gbl...
Craig,
In addition to Marek's comments.

> 1. The code the initiates any high-level user tasks should always be
> included in a try/catch block that actually handles any exceptions
> that

Disagree: In an effort to avoid duplicate code (try/catch/log
exception) I tend to leave exception logging to my global exception
handlers, instead I use try/finally & using statements to ensure any
resources are cleaned up.
There are lots of ways of solving problems - if it works for your
application that's great but I disagree with this as a general way of
handling exceptions.



Nov 16 '05 #13
David,
First I'm curious: Are you referring strictly to
AppDomain.UnhandledException or to all three Global Exception Handlers? As I
was referring to all three as a whole.
What if the app did not even know it was being run under a launcher? Consider the flip side. How does the launcher know the app you are calling
has its own exception handling? I hope you don't think the writer of the
launcher can "blindly" trust all the apps being launched are correctly
written so it doesn't need any exception handling!
The strategy may work for small, simple apps, but it does not scale. One could argue that all apps should be small & simple, especially ones that
are meant to scale. As I hope you agree that complexity leads to very
subtle, hard to reproduce/fix problems... So if using the Global Exception
Handlers reduces the amount of complexity in my code, then I will use them
unless said code is not compatible with the Global Exception Handlers! (such
as asynchronous methods). (In other words is the class half empty or is it
really half full?)
pushing the recovery off to some other piece of code, which may or may not
even execute, opens the app up to very subtle, hard to reproduce/fix
problems I agree, pushing the recovery off to the program being launched, which can
easily be forgotten, opens the app up to very subtle, hard to reproduce/fix
problems. Where as a Global Exception Handlers helps ensures that someone is
handling the exception, whether its the launchee or the launcher. I'm saying
"helps ensures" as I've seen where exceptions have been missed by even a
Global Exception Handlers, such as asynchronous methods. In other words if
anything I'm suggesting you really should have both! Especially if you are
using a launcher!

It appears (based on your earlier reference to UE) you are only referring
strictly to AppDomain.UnhandledException, where as I am referring to all
three Global Exception Handlers; AppDomain.UnhandledException,
HttpApplication.Error and Application.ThreadException. Plus I am suggesting
that you should use the one that is appropriate, I find
AppDomain.UnhandledException not to be very useful in most Windows Forms or
Web Forms applications. Instead I find Application.ThreadException to be
extremely useful in Windows Forms applications, and HttpApplication.Error &
Page.Error (TemplateControl.Error) to be extremely useful in Web Forms
applications. In other words: Pick the right tool for the right job!
I agree to disagree. Each time you make this recommendation to others I
will disagree. You are perfectly welcome to! If fact I hope you do, after all I am from a
free country that prides itself on freedom of speech. It does not make
either of our statements any more or less correct then the others statement.
In fact I actually agree you have a point, that the Global Exception
Handlers are not correct all the time, although I suspect they are correct
more times then you feel they are. I will save your posts and see about
rolling the intent of your comments into my FAQ.

BTW: If you re-read my statements I never stated that using Global Exception
Handlers are an absolute, I simply stated that is what I tended (normally)
used! I hope you agree that not using should not be an absolute either!

Hope this helps
Jay
"David Levine" <no******************@wi.rr.com> wrote in message
news:Or****************@TK2MSFTNGP11.phx.gbl... What if the app did not even know it was being run under a launcher? Also,
how do you determine that the code is correct, especially during a code
review? It's hard enough to look at a piece of code and determine that it
has correct error handling...pushing the recovery off to some other piece
of code, which may or may not even execute, opens the app up to very
subtle, hard to reproduce/fix problems. The strategy may work for small,
simple apps, but it does not scale.

I agree to disagree. Each time you make this recommendation to others I
will disagree.
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uZ***************@TK2MSFTNGP12.phx.gbl...
David,
If my app used a launcher, the launcher would be responsible for the UE,
so I really don't see your point.

I guess we will need to agree to disagree.

Hope this helps
Jay


Nov 16 '05 #14
First I'm curious: Are you referring strictly to
AppDomain.UnhandledException or to all three Global Exception Handlers? As
I was referring to all three as a whole.
As was I. BTW, there is only one true UE, the AppDomain.UE - the others are
actually events generated by different libraries that wrap execution threads
and generate the event when they catch an exception; typically the exception
gets swallowed. Some appear to use the subscription to the event as a
filter - if there is a subscription then the exception gets swallowed and
the event generated; if there are no subscriptions the exception propagates
up the call stack. It's been a while since I did the investigation and I
don't recall the details of which one does what.

What if the app did not even know it was being run under a launcher? Consider the flip side. How does the launcher know the app you are calling
has its own exception handling? I hope you don't think the writer of the
launcher can "blindly" trust all the apps being launched are correctly
written so it doesn't need any exception handling!


Of course the launcher does not make any assumptions whatsoever about the
code it launched - it has its own error handling to guard against buggy
apps.
The strategy may work for small, simple apps, but it does not scale. One could argue that all apps should be small & simple, especially ones
that are meant to scale.


One could make that argument, but it's silly to do so. Large problems
require large solutions, and not all problems, or applications, can be
reduced to a small, trivial size. You can modularize it, componentize it,
etc., and these are all good practices, but the fact remains that the parts
must be assembled into a whole. This is especially problematic with
exceptions because you now have a system comprised of separately designed
and built components (perhaps in different continents) that must
interoperate with each other, yet the effects of an unhandled event (a UE)
may be felt far beyond the boundaries of that component. It is the
non-local nature of exceptions that makes them so powerful and also so
dangerous.

Perhaps we have a philosophical disagreement.

I regard an exception as an error condition and I regard an unhandled
exception as a programming error. This states it in absolute terms and I
will also state that there are always exceptions to this rule, but in most
cases I find this to be accurate.

All execution threads should have a exception handler somewhere, if only to
ensure proper reporting and propagation of the error, and all code paths
must be known and testable. It is also desirable to make the code as
readable and understandable as possible, if for no other reason then the
make it easier to spot defects during a code review - using UEs to
communicate results makes this harder.

That is not to say that all exceptions should be swallowed...the exceptions
should continue to propagate until a handler is reached to deal with the
particular exception - ultimately to deal with all exceptions. It is only
that thread that has sufficient context to make the most correct decision on
how to proceed (e.g. Abort/retry/cancel). A UE handler simply has no context
to evaluate the situation.

The exception mechanism is also a uni-directional channel for information to
flow up the call stack - it reports on errors and other exceptional
conditions. It is loosely typed and does not provide a signature against
which a compiler can enforce usage, other then a generic Exception type (and
even that is not guaranteed, as you can catch, and presumably throw,
non-Exception derived types).

Exceptions are not a resource that can be dealt with the way that memory or
other managed resources are treated; there is no execution GC to correctly
clean up after a faulted thread. It is way too easy to get cleanup details
wrong. Sure, you can use finally blocks (and you should) for
transaction-oriented cleanup, but these are not always guaranteed to run,
and even if they do, the code must still be proven to be correct, and often
it isn't. The situation gets even more complex and murkier when there are
numerous asynchronous threads and interop involved, when nested exceptions
occur, when aborts get injected into threads, multiple appdomains are
involved, remoting, partially completed methods, objects left in an
indeterminate state, etc. It gets further complicated when adding in the
effects of versioning and system evolution.

Exception handling is a very complex subject and it cannot be reduced to a
few paragraphs here. It is tightly bound up with execution and thread
control, performance, correctness, robustness, and reliability. It doesn't
help that the tools to analyze data flow and execution control in
conjunction with exceptions are practically non-existent - it must be
hand-analyzed, and we all know the pitfalls of that.

I believe that using UEs for error handling results in less reliable, less
robust systems; there will be a natural tendency to ignore most exceptions
because something else, somewhere else, will deal with it...and this will
usually be the wrong way to deal with it.
As I hope you agree that complexity leads to very subtle, hard to
reproduce/fix problems... So if using the Global Exception Handlers
reduces the amount of complexity in my code, then I will use them unless
said code is not compatible with the Global Exception Handlers! (such as
asynchronous methods).
The code should never be more complex then it needs to be, but it should
especially not be less complex then it needs to be. Using UE as the primary
mechanism to deal with unanticipated problems make it far more complex (in
my opinion).
(In other words is the class half empty or is it really half full?)
I would argue that the glass is twice as large as it needs to be. :-)
pushing the recovery off to some other piece of code, which may or may
not even execute, opens the app up to very subtle, hard to reproduce/fix
problems I agree, pushing the recovery off to the program being launched, which can
easily be forgotten, opens the app up to very subtle, hard to
reproduce/fix problems. Where as a Global Exception Handlers helps ensures
that someone is handling the exception, whether its the launchee or the
launcher. I'm saying "helps ensures" as I've seen where exceptions have
been missed by even a Global Exception Handlers, such as asynchronous
methods. In other words if anything I'm suggesting you really should have
both! Especially if you are using a launcher!


You miss my point...there should always be a UE handler somewhere, if only
for the reason of logging the exception, and asking the user to continue or
abort. But that is simply a last-ditch effort! How would the user even know
if it was safe to continue? The user has no context to evaluate the system.
Conversely, how would the system know that it wasn't? What should be done in
a UE, and would that always be the correct decision in all cases?

It appears (based on your earlier reference to UE) you are only referring
strictly to AppDomain.UnhandledException, where as I am referring to all
three Global Exception Handlers; AppDomain.UnhandledException,
HttpApplication.Error and Application.ThreadException. Plus I am
suggesting that you should use the one that is appropriate, I find
AppDomain.UnhandledException not to be very useful in most Windows Forms
or Web Forms applications. Instead I find Application.ThreadException to
be extremely useful in Windows Forms applications, and
HttpApplication.Error & Page.Error (TemplateControl.Error) to be extremely
useful in Web Forms applications.
These are all useful for various purposes.

In other words: Pick the right tool for the right job! We can agree on this!
BTW: If you re-read my statements I never stated that using Global
Exception Handlers are an absolute, I simply stated that is what I tended
(normally) used! I hope you agree that not using should not be an absolute
either!


I never argued against using them at all. I argued against using them as the
primary mechanism for dealing with exceptions.

Hope this helps,
Dave
Nov 16 '05 #15
David,
As was I. BTW, there is only one true UE, the AppDomain.UE - the others
are actually events generated by different libraries that wrap execution
threads AppDomain.UnhandledException is an event also!
You miss my point...there should always be a UE handler somewhere, if only
for the reason of logging the exception, and asking the user to continue
or abort. That is exactly my point! I'm really not sure why you think I stated
otherwise...

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:Os**************@TK2MSFTNGP11.phx.gbl...
First I'm curious: Are you referring strictly to
AppDomain.UnhandledException or to all three Global Exception Handlers?
As I was referring to all three as a whole.


As was I. BTW, there is only one true UE, the AppDomain.UE - the others
are actually events generated by different libraries that wrap execution
threads and generate the event when they catch an exception; typically the
exception gets swallowed. Some appear to use the subscription to the event
as a filter - if there is a subscription then the exception gets swallowed
and the event generated; if there are no subscriptions the exception
propagates up the call stack. It's been a while since I did the
investigation and I don't recall the details of which one does what.

What if the app did not even know it was being run under a launcher?

Consider the flip side. How does the launcher know the app you are
calling has its own exception handling? I hope you don't think the writer
of the launcher can "blindly" trust all the apps being launched are
correctly written so it doesn't need any exception handling!


Of course the launcher does not make any assumptions whatsoever about the
code it launched - it has its own error handling to guard against buggy
apps.
The strategy may work for small, simple apps, but it does not scale.

One could argue that all apps should be small & simple, especially ones
that are meant to scale.


One could make that argument, but it's silly to do so. Large problems
require large solutions, and not all problems, or applications, can be
reduced to a small, trivial size. You can modularize it, componentize it,
etc., and these are all good practices, but the fact remains that the
parts must be assembled into a whole. This is especially problematic with
exceptions because you now have a system comprised of separately designed
and built components (perhaps in different continents) that must
interoperate with each other, yet the effects of an unhandled event (a UE)
may be felt far beyond the boundaries of that component. It is the
non-local nature of exceptions that makes them so powerful and also so
dangerous.

Perhaps we have a philosophical disagreement.

I regard an exception as an error condition and I regard an unhandled
exception as a programming error. This states it in absolute terms and I
will also state that there are always exceptions to this rule, but in most
cases I find this to be accurate.

All execution threads should have a exception handler somewhere, if only
to ensure proper reporting and propagation of the error, and all code
paths must be known and testable. It is also desirable to make the code as
readable and understandable as possible, if for no other reason then the
make it easier to spot defects during a code review - using UEs to
communicate results makes this harder.

That is not to say that all exceptions should be swallowed...the
exceptions should continue to propagate until a handler is reached to deal
with the particular exception - ultimately to deal with all exceptions. It
is only that thread that has sufficient context to make the most correct
decision on how to proceed (e.g. Abort/retry/cancel). A UE handler simply
has no context to evaluate the situation.

The exception mechanism is also a uni-directional channel for information
to flow up the call stack - it reports on errors and other exceptional
conditions. It is loosely typed and does not provide a signature against
which a compiler can enforce usage, other then a generic Exception type
(and even that is not guaranteed, as you can catch, and presumably throw,
non-Exception derived types).

Exceptions are not a resource that can be dealt with the way that memory
or other managed resources are treated; there is no execution GC to
correctly clean up after a faulted thread. It is way too easy to get
cleanup details wrong. Sure, you can use finally blocks (and you should)
for transaction-oriented cleanup, but these are not always guaranteed to
run, and even if they do, the code must still be proven to be correct, and
often it isn't. The situation gets even more complex and murkier when
there are numerous asynchronous threads and interop involved, when nested
exceptions occur, when aborts get injected into threads, multiple
appdomains are involved, remoting, partially completed methods, objects
left in an indeterminate state, etc. It gets further complicated when
adding in the effects of versioning and system evolution.

Exception handling is a very complex subject and it cannot be reduced to a
few paragraphs here. It is tightly bound up with execution and thread
control, performance, correctness, robustness, and reliability. It doesn't
help that the tools to analyze data flow and execution control in
conjunction with exceptions are practically non-existent - it must be
hand-analyzed, and we all know the pitfalls of that.

I believe that using UEs for error handling results in less reliable, less
robust systems; there will be a natural tendency to ignore most exceptions
because something else, somewhere else, will deal with it...and this will
usually be the wrong way to deal with it.
As I hope you agree that complexity leads to very subtle, hard to
reproduce/fix problems... So if using the Global Exception Handlers
reduces the amount of complexity in my code, then I will use them unless
said code is not compatible with the Global Exception Handlers! (such as
asynchronous methods).


The code should never be more complex then it needs to be, but it should
especially not be less complex then it needs to be. Using UE as the
primary mechanism to deal with unanticipated problems make it far more
complex (in my opinion).
(In other words is the class half empty or is it really half full?)


I would argue that the glass is twice as large as it needs to be. :-)
pushing the recovery off to some other piece of code, which may or may
not even execute, opens the app up to very subtle, hard to reproduce/fix
problems

I agree, pushing the recovery off to the program being launched, which
can easily be forgotten, opens the app up to very subtle, hard to
reproduce/fix problems. Where as a Global Exception Handlers helps
ensures that someone is handling the exception, whether its the launchee
or the launcher. I'm saying "helps ensures" as I've seen where exceptions
have been missed by even a Global Exception Handlers, such as
asynchronous methods. In other words if anything I'm suggesting you
really should have both! Especially if you are using a launcher!


You miss my point...there should always be a UE handler somewhere, if only
for the reason of logging the exception, and asking the user to continue
or abort. But that is simply a last-ditch effort! How would the user even
know if it was safe to continue? The user has no context to evaluate the
system. Conversely, how would the system know that it wasn't? What should
be done in a UE, and would that always be the correct decision in all
cases?

It appears (based on your earlier reference to UE) you are only referring
strictly to AppDomain.UnhandledException, where as I am referring to all
three Global Exception Handlers; AppDomain.UnhandledException,
HttpApplication.Error and Application.ThreadException. Plus I am
suggesting that you should use the one that is appropriate, I find
AppDomain.UnhandledException not to be very useful in most Windows Forms
or Web Forms applications. Instead I find Application.ThreadException to
be extremely useful in Windows Forms applications, and
HttpApplication.Error & Page.Error (TemplateControl.Error) to be
extremely useful in Web Forms applications.


These are all useful for various purposes.

In other words: Pick the right tool for the right job!

We can agree on this!
BTW: If you re-read my statements I never stated that using Global
Exception Handlers are an absolute, I simply stated that is what I tended
(normally) used! I hope you agree that not using should not be an
absolute either!


I never argued against using them at all. I argued against using them as
the primary mechanism for dealing with exceptions.

Hope this helps,
Dave

Nov 16 '05 #16
2 questions:

1) What is a launcher?

2) What do you mean by an exception being swallowed?

My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management. Looks
like I am going to have to invest some time studying the info in this
thread.

Are the two of you suggesting that unhandled exceptions should be allowed to
propagate up to a global exception handler which logs the exception and
closes down the app? This would mean that the following code should never
be used:

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.
"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:eC**************@TK2MSFTNGP10.phx.gbl...
David,
As was I. BTW, there is only one true UE, the AppDomain.UE - the others
are actually events generated by different libraries that wrap execution
threads

AppDomain.UnhandledException is an event also!
You miss my point...there should always be a UE handler somewhere, if
only for the reason of logging the exception, and asking the user to
continue or abort.

That is exactly my point! I'm really not sure why you think I stated
otherwise...

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:Os**************@TK2MSFTNGP11.phx.gbl...
First I'm curious: Are you referring strictly to
AppDomain.UnhandledException or to all three Global Exception Handlers?
As I was referring to all three as a whole.


As was I. BTW, there is only one true UE, the AppDomain.UE - the others
are actually events generated by different libraries that wrap execution
threads and generate the event when they catch an exception; typically
the exception gets swallowed. Some appear to use the subscription to the
event as a filter - if there is a subscription then the exception gets
swallowed and the event generated; if there are no subscriptions the
exception propagates up the call stack. It's been a while since I did the
investigation and I don't recall the details of which one does what.


What if the app did not even know it was being run under a launcher?
Consider the flip side. How does the launcher know the app you are
calling has its own exception handling? I hope you don't think the
writer of the launcher can "blindly" trust all the apps being launched
are correctly written so it doesn't need any exception handling!


Of course the launcher does not make any assumptions whatsoever about the
code it launched - it has its own error handling to guard against buggy
apps.

The strategy may work for small, simple apps, but it does not scale.
One could argue that all apps should be small & simple, especially ones
that are meant to scale.


One could make that argument, but it's silly to do so. Large problems
require large solutions, and not all problems, or applications, can be
reduced to a small, trivial size. You can modularize it, componentize it,
etc., and these are all good practices, but the fact remains that the
parts must be assembled into a whole. This is especially problematic with
exceptions because you now have a system comprised of separately designed
and built components (perhaps in different continents) that must
interoperate with each other, yet the effects of an unhandled event (a
UE) may be felt far beyond the boundaries of that component. It is the
non-local nature of exceptions that makes them so powerful and also so
dangerous.

Perhaps we have a philosophical disagreement.

I regard an exception as an error condition and I regard an unhandled
exception as a programming error. This states it in absolute terms and I
will also state that there are always exceptions to this rule, but in
most cases I find this to be accurate.

All execution threads should have a exception handler somewhere, if only
to ensure proper reporting and propagation of the error, and all code
paths must be known and testable. It is also desirable to make the code
as readable and understandable as possible, if for no other reason then
the make it easier to spot defects during a code review - using UEs to
communicate results makes this harder.

That is not to say that all exceptions should be swallowed...the
exceptions should continue to propagate until a handler is reached to
deal with the particular exception - ultimately to deal with all
exceptions. It is only that thread that has sufficient context to make
the most correct decision on how to proceed (e.g. Abort/retry/cancel). A
UE handler simply has no context to evaluate the situation.

The exception mechanism is also a uni-directional channel for information
to flow up the call stack - it reports on errors and other exceptional
conditions. It is loosely typed and does not provide a signature against
which a compiler can enforce usage, other then a generic Exception type
(and even that is not guaranteed, as you can catch, and presumably throw,
non-Exception derived types).

Exceptions are not a resource that can be dealt with the way that memory
or other managed resources are treated; there is no execution GC to
correctly clean up after a faulted thread. It is way too easy to get
cleanup details wrong. Sure, you can use finally blocks (and you should)
for transaction-oriented cleanup, but these are not always guaranteed to
run, and even if they do, the code must still be proven to be correct,
and often it isn't. The situation gets even more complex and murkier when
there are numerous asynchronous threads and interop involved, when nested
exceptions occur, when aborts get injected into threads, multiple
appdomains are involved, remoting, partially completed methods, objects
left in an indeterminate state, etc. It gets further complicated when
adding in the effects of versioning and system evolution.

Exception handling is a very complex subject and it cannot be reduced to
a few paragraphs here. It is tightly bound up with execution and thread
control, performance, correctness, robustness, and reliability. It
doesn't help that the tools to analyze data flow and execution control in
conjunction with exceptions are practically non-existent - it must be
hand-analyzed, and we all know the pitfalls of that.

I believe that using UEs for error handling results in less reliable,
less robust systems; there will be a natural tendency to ignore most
exceptions because something else, somewhere else, will deal with
it...and this will usually be the wrong way to deal with it.
As I hope you agree that complexity leads to very subtle, hard to
reproduce/fix problems... So if using the Global Exception Handlers
reduces the amount of complexity in my code, then I will use them unless
said code is not compatible with the Global Exception Handlers! (such as
asynchronous methods).


The code should never be more complex then it needs to be, but it should
especially not be less complex then it needs to be. Using UE as the
primary mechanism to deal with unanticipated problems make it far more
complex (in my opinion).
(In other words is the class half empty or is it really half full?)


I would argue that the glass is twice as large as it needs to be. :-)

pushing the recovery off to some other piece of code, which may or may
not even execute, opens the app up to very subtle, hard to
reproduce/fix problems
I agree, pushing the recovery off to the program being launched, which
can easily be forgotten, opens the app up to very subtle, hard to
reproduce/fix problems. Where as a Global Exception Handlers helps
ensures that someone is handling the exception, whether its the launchee
or the launcher. I'm saying "helps ensures" as I've seen where
exceptions have been missed by even a Global Exception Handlers, such as
asynchronous methods. In other words if anything I'm suggesting you
really should have both! Especially if you are using a launcher!


You miss my point...there should always be a UE handler somewhere, if
only for the reason of logging the exception, and asking the user to
continue or abort. But that is simply a last-ditch effort! How would the
user even know if it was safe to continue? The user has no context to
evaluate the system. Conversely, how would the system know that it
wasn't? What should be done in a UE, and would that always be the correct
decision in all cases?

It appears (based on your earlier reference to UE) you are only
referring strictly to AppDomain.UnhandledException, where as I am
referring to all three Global Exception Handlers;
AppDomain.UnhandledException, HttpApplication.Error and
Application.ThreadException. Plus I am suggesting that you should use
the one that is appropriate, I find AppDomain.UnhandledException not to
be very useful in most Windows Forms or Web Forms applications. Instead
I find Application.ThreadException to be extremely useful in Windows
Forms applications, and HttpApplication.Error & Page.Error
(TemplateControl.Error) to be extremely useful in Web Forms
applications.


These are all useful for various purposes.

In other words: Pick the right tool for the right job!

We can agree on this!
BTW: If you re-read my statements I never stated that using Global
Exception Handlers are an absolute, I simply stated that is what I
tended (normally) used! I hope you agree that not using should not be an
absolute either!


I never argued against using them at all. I argued against using them as
the primary mechanism for dealing with exceptions.

Hope this helps,
Dave


Nov 16 '05 #17

"craig" <e@mail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
2 questions:

1) What is a launcher?
A managed application that launches another windows (.net) application. It
could do so in a separate process, or load and execute it in another
appdomain within the same process; the latter is what I have been referring
to in the preceding dicussion.

2) What do you mean by an exception being swallowed? The following demonstrates swallowing an exception...
try
{
//evil code here
}
catch(Exception ex)
{
// trace, log, or ignore it. But it is not rethrown from within this
catch block
}

In this example, all exceptions will be caught in this catch block. Because
the exception is not rethrown then the exception ends here.
try
{
}
catch(NullReferenceException n)
{
}

In this case only a single exception type is caught, dealt with, and it ends
here. All other exception types are not caught so they continue to propagate
up the callstack.

{
}
catch(Exception ex)
{
if ( canHandleIt )
{ //handle and recover here
}
else
throw new Exception("I fell down and can't get up.",ex);
}

In this example, if the exception can be handled it is dealt with and ended
here, otherwise it is rethrown so that an exception continues to propagate
up the callstack. I used a new exception object, using the original
exception as the inner exception. I prefer this technique as you can add
valuable context information so that when it is eventually displayed to the
user s/he will get a better sense of what went wrong and can more
effectively deal with it. This referred to as the catch-wrap-throw
technique.

A variation on this is to use
catch(Exception ex)
{
// do some processing
throw;
}

A naked throw tells the CLR to continue to propagate the original exception
unchanged, including leaving the original stack trace alone (unfortunately,
in current version this actually resets it to the LOC where the throw is,
but that is supposed to be fixed).

I recommend against the following...
catch(Exception ex)
{
throw ex;
}
and
catch(Exception ex)
{
throw new SomeException("Some message")
}

The problem with the 1st is that it adds no additional information yet loses
the original stack trace. The 2nd has a similar problem and does not even
preserve the original exception type, so you lose even more data. However,
this form *might* be useful if this is a security sensitive operation and
you want to hide the real exception type.

I prefer the catch-wrap-throw technique as it adds info and does not lose
anything. I often times will throw the same exception type (i.e. I clone the
type) if there is no other type that I can map it to that adds useful
information.
My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management. Looks
like I am going to have to invest some time studying the info in this
thread.

Are the two of you suggesting that unhandled exceptions should be allowed
to propagate up to a global exception handler which logs the exception and
closes down the app? This would mean that the following code should never
be used:

If it is unhandled then by definition it is propagating upwards to a global
handler. If you do not provide one the system will provide a default action.
For UEs that occur on the main thread, or threads that originate from
unmanaged code, the application is terminated. For all other threads the UE
is discarded and you get no other indications that this occurred. The
terminate-or-run policy is currently set by the CLR itself, not the
application.

The app can subscribe to a UE event, and it can take some action within that
event, such as put up a messagebox, log it, etc., but if the system has
determined that the app should terminate the UE handler has no means of
changing that. In other words, if a UE occurs and the system decides it
should terminate the app, then wave bye-bye because you cannot change that
within the UE handler. There's a flag in the event args that indicates if
the app will terminate once the handler has run to completion.

When a UE occurs you can terminate the app on your own (call
Envurinment.Exit()) but you need to be aware that if you do then all other
threads in the system are frozen and never resume - this means that
unfinished finally blocks will not run and will never execute the clean up
code (this is v1.1 behavior - I don't know how this might have changed for
Whidbey).

This is one of the reasons I do not like the global UE strategy - you leave
the basic decision of terminating the app or allowing it to continue to the
system - I believe this ought to be an application policy decision.

You should have a registered handler, if for no other reason that exceptions
do not get "lost" when a UE occurs on a thread which will silently swallow
the exception - that's usually a bug.

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.

Like so many other things, it depends...this code may be fine; it depends on
what you want it to do. If the catch handler completely deals with it then
this is fine. If it does not, then if this is the final boundary of the
application you must make a call about whether to allow the app to run or
terminate it. If it is not, then you need some means to propagating the
exception upwards to the final handler in the system.


Nov 16 '05 #18
Craig,
1) What is a launcher? A launcher is a small program that loads your program & runs it. Useful for
(but not limited to) apps that dynamically update themselves from a web
site, but run locally. The launcher downloads the required assemblies & runs
them locally... The launcher itself may be installed locally, so as to allow
any required permissions needed...

2) What do you mean by an exception being swallowed? A try/catch or Global Exception Handler caught an exception & never let
other routines that called it or the user know. Depending on the calling &
called routines, this can be either a good thing or bad thing.

In the case of Global Exception Handlers, this can prevent your app from
terminating unexpectedly.

Are the two of you suggesting that unhandled exceptions should be allowed
to propagate up to a global exception handler which logs the exception and
closes down the app? If all I am doing with the exception is logging it, I am suggesting that
normally I allow a global exception handler log it (mainly to avoid
duplicate try/catch log blocks). If I have other "recovery" that is needed
to occur, then I use a try/catch block to perform the recovery. Depending on
where & what this recovery is I either log the exception, not log the
exception, rethrow the exception, or throw a new exception. Note that global
exception handlers really don't "recover" from exceptions, they can log the
exception & at a high level decide if the app should terminate or keep
going...

Hope this helps
Jay

"craig" <e@mail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...2 questions:

1) What is a launcher?

2) What do you mean by an exception being swallowed?

My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management. Looks
like I am going to have to invest some time studying the info in this
thread.

Are the two of you suggesting that unhandled exceptions should be allowed
to propagate up to a global exception handler which logs the exception and
closes down the app? This would mean that the following code should never
be used:

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.

<<snip>>
Nov 16 '05 #19
Thanks for the detailed exlplaination. I printed it out so that I can study
it.

Let me ask you this...

There is code in my app that follows this general pattern:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

}

I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. Would it be better to rewrite this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

myObject.Name = Name;

}
This allows an exception to be thrown with the next line of code attempts to
set the property of a null object reference. Or would it be better to write
this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

else

{

throw new InvalidArgumentException("ObjectID is invalid");

}

}
Thanks again for your input!!
"David Levine" <no******************@wi.rr.com> wrote in message
news:uI**************@tk2msftngp13.phx.gbl...

"craig" <e@mail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
2 questions:

1) What is a launcher?


A managed application that launches another windows (.net) application. It
could do so in a separate process, or load and execute it in another
appdomain within the same process; the latter is what I have been
referring to in the preceding dicussion.

2) What do you mean by an exception being swallowed?

The following demonstrates swallowing an exception...
try
{
//evil code here
}
catch(Exception ex)
{
// trace, log, or ignore it. But it is not rethrown from within this
catch block
}

In this example, all exceptions will be caught in this catch block.
Because the exception is not rethrown then the exception ends here.
try
{
}
catch(NullReferenceException n)
{
}

In this case only a single exception type is caught, dealt with, and it
ends here. All other exception types are not caught so they continue to
propagate up the callstack.

{
}
catch(Exception ex)
{
if ( canHandleIt )
{ //handle and recover here
}
else
throw new Exception("I fell down and can't get up.",ex);
}

In this example, if the exception can be handled it is dealt with and
ended here, otherwise it is rethrown so that an exception continues to
propagate up the callstack. I used a new exception object, using the
original exception as the inner exception. I prefer this technique as you
can add valuable context information so that when it is eventually
displayed to the user s/he will get a better sense of what went wrong and
can more effectively deal with it. This referred to as the
catch-wrap-throw technique.

A variation on this is to use
catch(Exception ex)
{
// do some processing
throw;
}

A naked throw tells the CLR to continue to propagate the original
exception unchanged, including leaving the original stack trace alone
(unfortunately, in current version this actually resets it to the LOC
where the throw is, but that is supposed to be fixed).

I recommend against the following...
catch(Exception ex)
{
throw ex;
}
and
catch(Exception ex)
{
throw new SomeException("Some message")
}

The problem with the 1st is that it adds no additional information yet
loses the original stack trace. The 2nd has a similar problem and does not
even preserve the original exception type, so you lose even more data.
However, this form *might* be useful if this is a security sensitive
operation and you want to hide the real exception type.

I prefer the catch-wrap-throw technique as it adds info and does not lose
anything. I often times will throw the same exception type (i.e. I clone
the type) if there is no other type that I can map it to that adds useful
information.
My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management.
Looks like I am going to have to invest some time studying the info in
this thread.

Are the two of you suggesting that unhandled exceptions should be allowed
to propagate up to a global exception handler which logs the exception
and closes down the app? This would mean that the following code should
never be used:


If it is unhandled then by definition it is propagating upwards to a
global handler. If you do not provide one the system will provide a
default action. For UEs that occur on the main thread, or threads that
originate from unmanaged code, the application is terminated. For all
other threads the UE is discarded and you get no other indications that
this occurred. The terminate-or-run policy is currently set by the CLR
itself, not the application.

The app can subscribe to a UE event, and it can take some action within
that event, such as put up a messagebox, log it, etc., but if the system
has determined that the app should terminate the UE handler has no means
of changing that. In other words, if a UE occurs and the system decides it
should terminate the app, then wave bye-bye because you cannot change that
within the UE handler. There's a flag in the event args that indicates if
the app will terminate once the handler has run to completion.

When a UE occurs you can terminate the app on your own (call
Envurinment.Exit()) but you need to be aware that if you do then all other
threads in the system are frozen and never resume - this means that
unfinished finally blocks will not run and will never execute the clean up
code (this is v1.1 behavior - I don't know how this might have changed for
Whidbey).

This is one of the reasons I do not like the global UE strategy - you
leave the basic decision of terminating the app or allowing it to continue
to the system - I believe this ought to be an application policy decision.

You should have a registered handler, if for no other reason that
exceptions do not get "lost" when a UE occurs on a thread which will
silently swallow the exception - that's usually a bug.

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.

Like so many other things, it depends...this code may be fine; it depends
on what you want it to do. If the catch handler completely deals with it
then this is fine. If it does not, then if this is the final boundary of
the application you must make a call about whether to allow the app to run
or terminate it. If it is not, then you need some means to propagating the
exception upwards to the final handler in the system.

Nov 16 '05 #20
I'm not Dave, but I do have an opinion on this (judge for yourself if it
makes sense..).

"craig" <e@mail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thanks for the detailed exlplaination. I printed it out so that I can
study it.

Let me ask you this...

There is code in my app that follows this general pattern:

Private void UpdateName(Guid ObjectID, String Name)
{
object myObject = GetObject(ObjectID)
if(myObject != null)
{
myObject.Name = Name;
}
}

I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. ...
Yes, there is this potential...
But sometimes in a world built around responding to events,
you could also have cases where a method could get called with null
parameters and you are just supposed to ignore the call if that happens.
Do you know if there was a reason that check was put in?

Now about the exception handling.... you do not want to do the first
thing. Clearly UpdateName is in a better position to give useful
information in the exception string than GetObject. That is,
UpdateName can tell you the NAME of the object you were
trying to update! All GetObject knows is that somebody passed it
a null parameter. If you want GetObject to raise the exception, you
should catch it, and throw again after adding to it. However, the
latter approach is probably better... probably there is no need to
involve GetObject. You already know the problem is a null
ObjectID.
Would it be better to rewrite this as:
Private void UpdateName(Guid ObjectID, String Name)
{
object myObject = GetObject(ObjectID)
myObject.Name = Name;
}

This allows an exception to be thrown with the next line of code attempts
to set the property of a null object reference. Or would it be better to
write this as:

Private void UpdateName(Guid ObjectID, String Name)
{
object myObject = GetObject(ObjectID)
if(myObject != null)
{
myObject.Name = Name;
}
else
{
throw new InvalidArgumentException("ObjectID is invalid");
}
}

Thanks again for your input!!

Nov 16 '05 #21
Craig,
I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. I would expect GetObject itself to throw the exception based on the bad
parameter!
If GetObject can return "null objects", then I would consider having
GetObject return a Null Object.

A Null Object is an implementation of the Special Case Pattern.

http://martinfowler.com/eaaCatalog/specialCase.html

Hope this helps
Jay

"craig" <e@mail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... Thanks for the detailed exlplaination. I printed it out so that I can
study it.

Let me ask you this...

There is code in my app that follows this general pattern:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

}

I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. Would it be better to rewrite this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

myObject.Name = Name;

}
This allows an exception to be thrown with the next line of code attempts
to set the property of a null object reference. Or would it be better to
write this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

else

{

throw new InvalidArgumentException("ObjectID is invalid");

}

}
Thanks again for your input!!

<<snip>>
Nov 16 '05 #22

"craig" <e@mail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thanks for the detailed exlplaination. I printed it out so that I can
study it.

Let me ask you this...

There is code in my app that follows this general pattern:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

}

I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. Would it be better to rewrite this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

myObject.Name = Name;

}
This allows an exception to be thrown with the next line of code attempts
to set the property of a null object reference. Or would it be better to
write this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

else

{

throw new InvalidArgumentException("ObjectID is invalid");

}

}
Thanks again for your input!!
"David Levine" <no******************@wi.rr.com> wrote in message
news:uI**************@tk2msftngp13.phx.gbl...

"craig" <e@mail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
2 questions:

1) What is a launcher?


A managed application that launches another windows (.net) application.
It could do so in a separate process, or load and execute it in another
appdomain within the same process; the latter is what I have been
referring to in the preceding dicussion.

2) What do you mean by an exception being swallowed?

The following demonstrates swallowing an exception...
try
{
//evil code here
}
catch(Exception ex)
{
// trace, log, or ignore it. But it is not rethrown from within this
catch block
}

In this example, all exceptions will be caught in this catch block.
Because the exception is not rethrown then the exception ends here.
try
{
}
catch(NullReferenceException n)
{
}

In this case only a single exception type is caught, dealt with, and it
ends here. All other exception types are not caught so they continue to
propagate up the callstack.

{
}
catch(Exception ex)
{
if ( canHandleIt )
{ //handle and recover here
}
else
throw new Exception("I fell down and can't get up.",ex);
}

In this example, if the exception can be handled it is dealt with and
ended here, otherwise it is rethrown so that an exception continues to
propagate up the callstack. I used a new exception object, using the
original exception as the inner exception. I prefer this technique as you
can add valuable context information so that when it is eventually
displayed to the user s/he will get a better sense of what went wrong and
can more effectively deal with it. This referred to as the
catch-wrap-throw technique.

A variation on this is to use
catch(Exception ex)
{
// do some processing
throw;
}

A naked throw tells the CLR to continue to propagate the original
exception unchanged, including leaving the original stack trace alone
(unfortunately, in current version this actually resets it to the LOC
where the throw is, but that is supposed to be fixed).

I recommend against the following...
catch(Exception ex)
{
throw ex;
}
and
catch(Exception ex)
{
throw new SomeException("Some message")
}

The problem with the 1st is that it adds no additional information yet
loses the original stack trace. The 2nd has a similar problem and does
not even preserve the original exception type, so you lose even more
data. However, this form *might* be useful if this is a security
sensitive operation and you want to hide the real exception type.

I prefer the catch-wrap-throw technique as it adds info and does not lose
anything. I often times will throw the same exception type (i.e. I clone
the type) if there is no other type that I can map it to that adds useful
information.
My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management.
Looks like I am going to have to invest some time studying the info in
this thread.

Are the two of you suggesting that unhandled exceptions should be
allowed to propagate up to a global exception handler which logs the
exception and closes down the app? This would mean that the following
code should never be used:


If it is unhandled then by definition it is propagating upwards to a
global handler. If you do not provide one the system will provide a
default action. For UEs that occur on the main thread, or threads that
originate from unmanaged code, the application is terminated. For all
other threads the UE is discarded and you get no other indications that
this occurred. The terminate-or-run policy is currently set by the CLR
itself, not the application.

The app can subscribe to a UE event, and it can take some action within
that event, such as put up a messagebox, log it, etc., but if the system
has determined that the app should terminate the UE handler has no means
of changing that. In other words, if a UE occurs and the system decides
it should terminate the app, then wave bye-bye because you cannot change
that within the UE handler. There's a flag in the event args that
indicates if the app will terminate once the handler has run to
completion.

When a UE occurs you can terminate the app on your own (call
Envurinment.Exit()) but you need to be aware that if you do then all
other threads in the system are frozen and never resume - this means that
unfinished finally blocks will not run and will never execute the clean
up code (this is v1.1 behavior - I don't know how this might have changed
for Whidbey).

This is one of the reasons I do not like the global UE strategy - you
leave the basic decision of terminating the app or allowing it to
continue to the system - I believe this ought to be an application policy
decision.

You should have a registered handler, if for no other reason that
exceptions do not get "lost" when a UE occurs on a thread which will
silently swallow the exception - that's usually a bug.

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.

Like so many other things, it depends...this code may be fine; it depends
on what you want it to do. If the catch handler completely deals with it
then this is fine. If it does not, then if this is the final boundary of
the application you must make a call about whether to allow the app to
run or terminate it. If it is not, then you need some means to
propagating the exception upwards to the final handler in the system.


Nov 16 '05 #23
Rachel and Jay made some good points. Let me give my two (or more) cents..

I see this as a problem with several parts.

The first is whether or not the routine should perform parameter validation
before processing the values. If this is an internal routine then other
routines at the class boundary should perform complete parameter validation
before handing it off to the internal routines. In general you should
centralize the validation logic for two reasons - one, it's a lot easier to
test and maintain and ensures coherency, and two, this means that internal
routines don't have to burn CPU cycles performing the same checking. If an
argument fails the validation check then it is acceptable to throw an
exception that describes the causes of the failure.

The second aspect of the problem is determining what constitutes a valid
value. In some cases null might be perfectly acceptable and in others it is
invalid. Generally speaking there is no such thing as a single value that
for all classes and uses will always represent an invalid value - it depends
on what you are doing. For the ObjectID there might be more then one value
that represents an invalid value; for example null, and an empty guid might
both be invalid. There may be others, such as a predefined sentinel value
that represents some kind of special case, such as the last ObjectID in the
system.

Another aspect is what does it mean to return a null object from GetObject?
Is this a valid case? For some systems it may be that if the objectID passes
parameter validation then it is a violation of some internal contract for
the call to GetObject to return a null object - in this case it should throw
an exception indicating an internal error. For other systems it may be
"normal" for a record to not be found - in this case you would not want to
throw an exception, instead there should be a code path that is correct for
that case.

So I don't have a single answer...it depends on the design and intent of the
system.

That being said, if you do want to validate parameters in this method I
would do so before calling GetObject, and if it fails, throw an exception
immediately. As I said earlier, because it is a private method I would
actually expect validation to occur somewhere else.

In the example you provide I would not let an exception be thrown just
because you attempted to set the property of a null reference; this will
generate a misleading exception message to the user (telling your user his
program crashed due to an access violation will not win many friends).
Again, if it is expected that some records will not be found then I would
make a null return object part of a normal code path. However, if this
represents a violation of an internal contract then I suppose in that case
it is not something I would test. Ideally this sort of failure should be
detected and dealt with in a different layer, probably in the GetObject
method itself.

Hope this helps,
Dave
"craig" <e@mail.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thanks for the detailed exlplaination. I printed it out so that I can
study it.

Let me ask you this...

There is code in my app that follows this general pattern:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

}

I see this as a problem, because it has the potential to swallow a logic
error in which an invalid ObjectID parameter is passed resulting in the
GetObject method returning null. Would it be better to rewrite this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

myObject.Name = Name;

}
This allows an exception to be thrown with the next line of code attempts
to set the property of a null object reference. Or would it be better to
write this as:

Private void UpdateName(Guid ObjectID, String Name)

{

object myObject = GetObject(ObjectID)

if(myObject != null)

{

myObject.Name = Name;

}

else

{

throw new InvalidArgumentException("ObjectID is invalid");

}

}
Thanks again for your input!!
"David Levine" <no******************@wi.rr.com> wrote in message
news:uI**************@tk2msftngp13.phx.gbl...

"craig" <e@mail.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
2 questions:

1) What is a launcher?


A managed application that launches another windows (.net) application.
It could do so in a separate process, or load and execute it in another
appdomain within the same process; the latter is what I have been
referring to in the preceding dicussion.

2) What do you mean by an exception being swallowed?

The following demonstrates swallowing an exception...
try
{
//evil code here
}
catch(Exception ex)
{
// trace, log, or ignore it. But it is not rethrown from within this
catch block
}

In this example, all exceptions will be caught in this catch block.
Because the exception is not rethrown then the exception ends here.
try
{
}
catch(NullReferenceException n)
{
}

In this case only a single exception type is caught, dealt with, and it
ends here. All other exception types are not caught so they continue to
propagate up the callstack.

{
}
catch(Exception ex)
{
if ( canHandleIt )
{ //handle and recover here
}
else
throw new Exception("I fell down and can't get up.",ex);
}

In this example, if the exception can be handled it is dealt with and
ended here, otherwise it is rethrown so that an exception continues to
propagate up the callstack. I used a new exception object, using the
original exception as the inner exception. I prefer this technique as you
can add valuable context information so that when it is eventually
displayed to the user s/he will get a better sense of what went wrong and
can more effectively deal with it. This referred to as the
catch-wrap-throw technique.

A variation on this is to use
catch(Exception ex)
{
// do some processing
throw;
}

A naked throw tells the CLR to continue to propagate the original
exception unchanged, including leaving the original stack trace alone
(unfortunately, in current version this actually resets it to the LOC
where the throw is, but that is supposed to be fixed).

I recommend against the following...
catch(Exception ex)
{
throw ex;
}
and
catch(Exception ex)
{
throw new SomeException("Some message")
}

The problem with the 1st is that it adds no additional information yet
loses the original stack trace. The 2nd has a similar problem and does
not even preserve the original exception type, so you lose even more
data. However, this form *might* be useful if this is a security
sensitive operation and you want to hide the real exception type.

I prefer the catch-wrap-throw technique as it adds info and does not lose
anything. I often times will throw the same exception type (i.e. I clone
the type) if there is no other type that I can map it to that adds useful
information.
My app is a windows forms app and I am really struggling to find a
consistent, logical strategy for implementing exception management.
Looks like I am going to have to invest some time studying the info in
this thread.

Are the two of you suggesting that unhandled exceptions should be
allowed to propagate up to a global exception handler which logs the
exception and closes down the app? This would mean that the following
code should never be used:


If it is unhandled then by definition it is propagating upwards to a
global handler. If you do not provide one the system will provide a
default action. For UEs that occur on the main thread, or threads that
originate from unmanaged code, the application is terminated. For all
other threads the UE is discarded and you get no other indications that
this occurred. The terminate-or-run policy is currently set by the CLR
itself, not the application.

The app can subscribe to a UE event, and it can take some action within
that event, such as put up a messagebox, log it, etc., but if the system
has determined that the app should terminate the UE handler has no means
of changing that. In other words, if a UE occurs and the system decides
it should terminate the app, then wave bye-bye because you cannot change
that within the UE handler. There's a flag in the event args that
indicates if the app will terminate once the handler has run to
completion.

When a UE occurs you can terminate the app on your own (call
Envurinment.Exit()) but you need to be aware that if you do then all
other threads in the system are frozen and never resume - this means that
unfinished finally blocks will not run and will never execute the clean
up code (this is v1.1 behavior - I don't know how this might have changed
for Whidbey).

This is one of the reasons I do not like the global UE strategy - you
leave the basic decision of terminating the app or allowing it to
continue to the system - I believe this ought to be an application policy
decision.

You should have a registered handler, if for no other reason that
exceptions do not get "lost" when a UE occurs on a thread which will
silently swallow the exception - that's usually a bug.

try
{
//program logic
}
catch(Exception ex)
{
//response to exception
}

I have used code like this all over in my app.

Like so many other things, it depends...this code may be fine; it depends
on what you want it to do. If the catch handler completely deals with it
then this is fine. If it does not, then if this is the final boundary of
the application you must make a call about whether to allow the app to
run or terminate it. If it is not, then you need some means to
propagating the exception upwards to the final handler in the system.


Nov 16 '05 #24

"craig" <e@mail.com> wrote in message
news:OI**************@TK2MSFTNGP14.phx.gbl...
I can't thank all of you enough for taking the time to weigh in on this
issue. It blows my mind how much thought must go into what might at first
appear to be some very simple logic.
Even the simplest of things is not simple at all. When looking at my code I
usually take the attitude that
every line of code is flawed or will be flawed. Doesn't necessarily mean
there's a bug lurking there (though all too often there is), but as systems
evolve and environments change even the most inocuous statements will be
revealed as containing a weakness or which can be improved. Doesn't mean you
want to churn the code base for minor improvements; it means to always think
about what could go wrong.

This is especially true for .NET code since it's possible for literally
almost every line of code to be capable of causing an exception.

Rachel's point about methods being called with null parameters simply
because of the way events are firing is very relevant. This happens to me
all the time. I often find methods being called at seemingly
indeterminate times because of the way events are fired which always
raises the question: does this indeterminate firing of events constitute a
logic error which needs to be sorted out and corrected, or should I just
design the method to swallow the null parameter case in order to be able
to accomodate this behavior without failure??? I often wonder how other
developers handle this issue.
Events are a little special in that they often contain arguments which are
not always required by the invoked event, in which case one or more null
arguments can be ignored. However, they should never be fired
indeterminately (randomly?)...it may our understanding of them is incomplete
but the behavior of the system should be predictable. There is no magic,
only a machine behind that curtain...

Based in your responses, it sounds as though there are no clearly-defined
patterns. Different developers might handle this situation in different
ways. It is not easy to know which is the most robust. However, I am not
familiar with the concept of a common parameter validation routine for use
with private methods. Do you mean to define methods used specifically for
validating each parameter which are called prior to calling the private
methods in which the parameters are used?

I am not aware of a single pattern that covers all the cases.
The basic idea is simple - validate the data once at the input point to the
system so that internal objects and routines can assume the data has already
been validated. Data from the outside world cannot be trusted to be valid (a
hacker may be prodding the system) but once inside it is considered to be
trusted. How you actually implement this depends on the complexity of the
validation logic - simple things should be done inline, complex things
should be separated out as much as is necessary.

You can put validation logic in each routine, and that's not necessarily a
bad thing, but often it results in code bloat, burns CPU cycles, and spreads
the validation logic all over the source code, making it difficult to
maintain. The advantage of is that makes your code more bullet proof, even
from internal errors. In a mission critical system where robustness is more
important than shaving a few processing cycles this might be a valid
approach.


Nov 16 '05 #25

"David Levine" <no******************@wi.rr.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...

. . . This is especially true for .NET code since it's possible for
literally almost every line of code to be capable of causing an exception.
<sigh> and yet we're supposed to know at all times what exceptions can be
thrown...

. . . I often find methods being called at seemingly indeterminate times
because of the way events are fired . . .


Events are a little special . . . However, they should never be fired
indeterminately (randomly?)...it may our understanding of them is
incomplete but the behavior of the system should be predictable. There is
no magic, only a machine behind that curtain...


Sometimes I think that events are only not random in the same sense that
nothing is ever random. Everything behaves the way it does for some reason,
according to some set of rules (pysical laws, whatever), but when a stystem
is so complex that the behavior of a particular event is unpredictable, then
it is considered random. I'm sure it is just my frustration at an
unproductive day, but doesn't it seem that the monstrous set of events that
comes built in with our .NET is approaching that level of complexity? I
wonder if it's really simpler and easier to learn than reading a
straightforward message loop...

But you are right, if we think about it well enough, I think we can always
solve our problems. If only our bosses wouldn't give us these darned
annoying deadlines that never give us enough time to think things through!!

. . .

. . .
The basic idea is simple - validate the data once at the input point to
the system so that internal objects and routines can assume the data has
already been validated. Data from the outside world cannot be trusted to
be valid (a hacker may be prodding the system) but once inside it is
considered to be trusted.


I cut my last message short in the hopes someone smarter than me would get
to what I was going to take way too long trying to say. Thanks for not
disappointing me :-)
You can put validation logic in each routine, and that's not necessarily a
bad thing, but often it results in code bloat, . . .


and that is where exceptions come in. If you don't force validation in every
interior function, you could let exceptions go, they will help to catch
those times where you forget to validate something you should've. Ugh, that
contradicts my previous response doesn't it? You see why no one can agree on
how to do error handling? I can't even agree with myself. They key is to
find a system that will do these two things.
1) It will not send the user multiple messages about the same error.
2) When it does send messages to the user, they will mean something (that
is, they will not say "object not set to an instance." That not only means
nothing to the user, it will mean nothing to the programmer if the user
reports it. He won't know which of the 65,482 objects in his program wasn't
set to an instance, nor will he even know where it wasn't set because if I'm
not mistaken, the user doesn't get the stack trace in production code.)
Nov 16 '05 #26

"Rachel Suddeth" <ra****@bldhound.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...

"David Levine" <no******************@wi.rr.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...

. . . This is especially true for .NET code since it's possible for
literally almost every line of code to be capable of causing an
exception.
<sigh> and yet we're supposed to know at all times what exceptions can be
thrown...


I actually don't make the assumption that I know which *specific* exceptions
will be thrown, only that *an* exception can be thrown. I try to structure
the subsystems so that I know the path that exceptions will take as it
propagates through the system. There are situations where I will catch
specific exceptions and try to handle them but I've found that there are
more exceptions I did not anticipate then there are that I can account for.

Sometimes I think that events are only not random in the same sense that
nothing is ever random. Everything behaves the way it does for some
reason, according to some set of rules (pysical laws, whatever), but when
a stystem is so complex that the behavior of a particular event is
unpredictable, then it is considered random.
I quite agree. Chaos theory rules...
I'm sure it is just my frustration at an unproductive day, but doesn't it
seem that the monstrous set of events that comes built in with our .NET is
approaching that level of complexity? I wonder if it's really simpler and
easier to learn than reading a straightforward message loop...
I don't see this as a .NET problem but more as a system problem. The
combination of .NET, the COM/C++ libs it is built on, and the windowing
system below it, is incredibly complex. Even a straight message loop really
isn't so straight when you trace the passage of an event all the way from
the hardware device that originally generated the event to the trap handler
to the interrupt handler in the device driver, through the kernel, up to
user mode, up to the windows subsystem, etc.


and that is where exceptions come in. If you don't force validation in
every interior function, you could let exceptions go, they will help to
catch those times where you forget to validate something you should've.
Ugh, that contradicts my previous response doesn't it? You see why no one
can agree on how to do error handling? I can't even agree with myself.
And that's the rub. No matter how well written the code there are always
unforseen conditions that the code did not anticipate; foolproof code isn't
proof against all fools.

There's an inherent tension between the desire to centralize code and
eliminate duplication versus bullet-proofing every method that performs
sensitive operations. There isn't a single design that will work for all
systems - the requirements of the system should drive it, not some ivory
tower notion of the proper way of writing code. In mission critical software
I've written a lot of self-defensive code to guard against internal errors,
and sure enough those errors happen. It might only catch a one-in-a-million
bug, and perhaps I'm too paranoid, but I'd rather err on the side of safety
rather then assume the best. I think this matters more the more that the
code interacts with outside systems.
They key is to find a system that will do these two things.
1) It will not send the user multiple messages about the same error.
2) When it does send messages to the user, they will mean something (that
is, they will not say "object not set to an instance." That not only means
nothing to the user, it will mean nothing to the programmer if the user
reports it.
I agree! The problem is not that there is no information but that the
information is either misleading or so incomplete that it is very difficult
to do much with. I really don't want to have to do a core dump, hook up
windbg and trace through system data structures just to determine that an
array index was off by 1!

In my exception management layer I wrote a PublishOnCreate method which
determines if the exception is being thrown for the first time or is being
wrapped and rethrown - it publishes it at the initial throw site and not at
the intermediate sites. Then at the final handler I publish it again - this
captures the initial exception and also the final disposition at the module
boundary, including all the context information that had been added. I do
this double-publish to ensure I have a record even if an exception is
accidently swallowed and ignored.

I haven't worked out my strategy yet for Whidbey. There are some new events
that you can subscribe to that get fired whenever an exception is thrown at
all - this seems like a promising avenue to use for ensuring that exceptions
do not get dropped or lost, but it also has the potential for swamping a
system.

He won't know which of the 65,482 objects in his program wasn't set to an
instance, nor will he even know where it wasn't set because if I'm not
mistaken, the user doesn't get the stack trace in production code.)


Hmmm, it may not be able to provide lines numbers and source file names, but
a stack trace should always be available.
Nov 16 '05 #27

"David Levine" <no******************@wi.rr.com> wrote in message
news:eJ****************@TK2MSFTNGP10.phx.gbl...

"Rachel Suddeth" <ra****@bldhound.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...

"David Levine" <no******************@wi.rr.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...

. . . This is especially true for .NET code since it's possible for
literally almost every line of code to be capable of causing an
exception.
<sigh> and yet we're supposed to know at all times what exceptions can be
thrown...


I actually don't make the assumption that I know which *specific*
exceptions will be thrown, only that *an* exception can be thrown. I try
to structure the subsystems so that I know the path that exceptions will
take as it propagates through the system. There are situations where I
will catch specific exceptions and try to handle them but I've found that
there are more exceptions I did not anticipate then there are that I can
account for.

Sometimes I think that events are only not random in the same sense that
nothing is ever random. Everything behaves the way it does for some
reason, according to some set of rules (pysical laws, whatever), but when
a stystem is so complex that the behavior of a particular event is
unpredictable, then it is considered random.


I quite agree. Chaos theory rules...
I'm sure it is just my frustration at an unproductive day, but doesn't it
seem that the monstrous set of events that comes built in with our .NET
is approaching that level of complexity? I wonder if it's really simpler
and easier to learn than reading a straightforward message loop...


I don't see this as a .NET problem but more as a system problem. The
combination of .NET, the COM/C++ libs it is built on, and the windowing
system below it, is incredibly complex. Even a straight message loop
really isn't so straight when you trace the passage of an event all the
way from the hardware device that originally generated the event to the
trap handler to the interrupt handler in the device driver, through the
kernel, up to user mode, up to the windows subsystem, etc.


and that is where exceptions come in. If you don't force validation in
every interior function, you could let exceptions go, they will help to
catch those times where you forget to validate something you should've.
Ugh, that contradicts my previous response doesn't it? You see why no one
can agree on how to do error handling? I can't even agree with myself.


And that's the rub. No matter how well written the code there are always
unforseen conditions that the code did not anticipate; foolproof code
isn't proof against all fools.

There's an inherent tension between the desire to centralize code and
eliminate duplication versus bullet-proofing every method that performs
sensitive operations. There isn't a single design that will work for all
systems - the requirements of the system should drive it, not some ivory
tower notion of the proper way of writing code. In mission critical
software I've written a lot of self-defensive code to guard against
internal errors, and sure enough those errors happen. It might only catch
a one-in-a-million bug, and perhaps I'm too paranoid, but I'd rather err
on the side of safety rather then assume the best. I think this matters
more the more that the code interacts with outside systems.


This is my struggle as well. I realize that I can validate all of the
incoming data at one time therefore allowing all private methods to assume
that this data is valid. The problem with this, however, is that potential
internal logic errors might still result in invalid parameters being passed
to private methods. These logic errors might be easier to track down if all
of the private methods also validate parameters as well.


They key is to find a system that will do these two things.
1) It will not send the user multiple messages about the same error.
2) When it does send messages to the user, they will mean something (that
is, they will not say "object not set to an instance." That not only
means nothing to the user, it will mean nothing to the programmer if the
user reports it.


I agree! The problem is not that there is no information but that the
information is either misleading or so incomplete that it is very
difficult to do much with. I really don't want to have to do a core dump,
hook up windbg and trace through system data structures just to determine
that an array index was off by 1!

In my exception management layer I wrote a PublishOnCreate method which
determines if the exception is being thrown for the first time or is being
wrapped and rethrown - it publishes it at the initial throw site and not
at the intermediate sites. Then at the final handler I publish it again -
this captures the initial exception and also the final disposition at the
module boundary, including all the context information that had been
added. I do this double-publish to ensure I have a record even if an
exception is accidently swallowed and ignored.

I haven't worked out my strategy yet for Whidbey. There are some new
events that you can subscribe to that get fired whenever an exception is
thrown at all - this seems like a promising avenue to use for ensuring
that exceptions do not get dropped or lost, but it also has the potential
for swamping a system.

He won't know which of the 65,482 objects in his program wasn't set to an
instance, nor will he even know where it wasn't set because if I'm not
mistaken, the user doesn't get the stack trace in production code.)


Hmmm, it may not be able to provide lines numbers and source file names,
but a stack trace should always be available.

Nov 16 '05 #28
I also thought I would mention the following...

One of my very favorite books on the .NET Framework is Jeffrey Richter's
"Applied Microsoft .NET Framework Programming." I just noticed that he has
an excellent chapter on exception management stratgey which includes many of
the concpets that have been discussed here. I would highly recommend this
book. I hope that he is planning an update for the 2.0 framework.
"David Levine" <no******************@wi.rr.com> wrote in message
news:eJ****************@TK2MSFTNGP10.phx.gbl...

"Rachel Suddeth" <ra****@bldhound.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...

"David Levine" <no******************@wi.rr.com> wrote in message
news:%2****************@TK2MSFTNGP15.phx.gbl...

. . . This is especially true for .NET code since it's possible for
literally almost every line of code to be capable of causing an
exception.

<sigh> and yet we're supposed to know at all times what exceptions can be
thrown...


I actually don't make the assumption that I know which *specific*
exceptions will be thrown, only that *an* exception can be thrown. I try
to structure the subsystems so that I know the path that exceptions will
take as it propagates through the system. There are situations where I
will catch specific exceptions and try to handle them but I've found that
there are more exceptions I did not anticipate then there are that I can
account for.

Sometimes I think that events are only not random in the same sense that
nothing is ever random. Everything behaves the way it does for some
reason, according to some set of rules (pysical laws, whatever), but when
a stystem is so complex that the behavior of a particular event is
unpredictable, then it is considered random.


I quite agree. Chaos theory rules...
I'm sure it is just my frustration at an unproductive day, but doesn't it
seem that the monstrous set of events that comes built in with our .NET
is approaching that level of complexity? I wonder if it's really simpler
and easier to learn than reading a straightforward message loop...


I don't see this as a .NET problem but more as a system problem. The
combination of .NET, the COM/C++ libs it is built on, and the windowing
system below it, is incredibly complex. Even a straight message loop
really isn't so straight when you trace the passage of an event all the
way from the hardware device that originally generated the event to the
trap handler to the interrupt handler in the device driver, through the
kernel, up to user mode, up to the windows subsystem, etc.


and that is where exceptions come in. If you don't force validation in
every interior function, you could let exceptions go, they will help to
catch those times where you forget to validate something you should've.
Ugh, that contradicts my previous response doesn't it? You see why no one
can agree on how to do error handling? I can't even agree with myself.


And that's the rub. No matter how well written the code there are always
unforseen conditions that the code did not anticipate; foolproof code
isn't proof against all fools.

There's an inherent tension between the desire to centralize code and
eliminate duplication versus bullet-proofing every method that performs
sensitive operations. There isn't a single design that will work for all
systems - the requirements of the system should drive it, not some ivory
tower notion of the proper way of writing code. In mission critical
software I've written a lot of self-defensive code to guard against
internal errors, and sure enough those errors happen. It might only catch
a one-in-a-million bug, and perhaps I'm too paranoid, but I'd rather err
on the side of safety rather then assume the best. I think this matters
more the more that the code interacts with outside systems.
They key is to find a system that will do these two things.
1) It will not send the user multiple messages about the same error.
2) When it does send messages to the user, they will mean something (that
is, they will not say "object not set to an instance." That not only
means nothing to the user, it will mean nothing to the programmer if the
user reports it.


I agree! The problem is not that there is no information but that the
information is either misleading or so incomplete that it is very
difficult to do much with. I really don't want to have to do a core dump,
hook up windbg and trace through system data structures just to determine
that an array index was off by 1!

In my exception management layer I wrote a PublishOnCreate method which
determines if the exception is being thrown for the first time or is being
wrapped and rethrown - it publishes it at the initial throw site and not
at the intermediate sites. Then at the final handler I publish it again -
this captures the initial exception and also the final disposition at the
module boundary, including all the context information that had been
added. I do this double-publish to ensure I have a record even if an
exception is accidently swallowed and ignored.

I haven't worked out my strategy yet for Whidbey. There are some new
events that you can subscribe to that get fired whenever an exception is
thrown at all - this seems like a promising avenue to use for ensuring
that exceptions do not get dropped or lost, but it also has the potential
for swamping a system.

He won't know which of the 65,482 objects in his program wasn't set to an
instance, nor will he even know where it wasn't set because if I'm not
mistaken, the user doesn't get the stack trace in production code.)


Hmmm, it may not be able to provide lines numbers and source file names,
but a stack trace should always be available.

Nov 16 '05 #29

"David Levine" <no******************@wi.rr.com> wrote in message
news:eJ****************@TK2MSFTNGP10.phx.gbl...

"Rachel Suddeth" <ra****@bldhound.com> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...

. . .
Sometimes I think that events are only not random in the same sense that
nothing is ever random. . . .doesn't it seem that the monstrous set
of events that comes built in with our .NET is approaching that level of
complexity? I wonder if it's really simpler and easier to learn than
reading a straightforward message loop...
I don't see this as a .NET problem but more as a system problem.. .


Funny, I just thought that shortly after sending the previous message. Part
of the issue is I'm new to Windows programming. Although I've read Windows
code (straight C versions of it), and done a couple of kindergarten
utilities in VB, I've only been doing real work in it for about 6 months.
Previously I worked [in tools and] with embedded systems programming on
special operating system that was probably much more simple than Windows.
Although the message loops looked similar, I think one can get a much
greater variety of messages, and from more different sources, AND you're
expected to deal with it with less training - which is why they hide the
details, eh?

. . . In mission critical software I've written a lot of self-defensive
code to guard against internal errors, and sure enough those errors
happen. It might only catch a one-in-a-million bug, and perhaps I'm too
paranoid,
Probably not. If a mistake or oversight could bring down a drawbrige on top
of a boat, or shut down a power grid, or cause a missile to hit the wrong
target, or make your customer loose 1/2 million on the stock market, then
you can't be too careful, and you expect most of your code to be error
handling. In a complex system, there are an almost infinite number of errors
that can happen, so the one in a million things occasionally do.

Personally, I am enjoying working in an environment where poorly handled
errors don't cause any actual disasters :-) [Although from talking to some
of our clients, you would think wasting a ream of paper was a disaster...]
. . .
I haven't worked out my strategy yet for Whidbey.
For what? Oh dear, I'm missing things again. Out of the loop as usual...
Hmmm, it may not be able to provide lines numbers and source file names,
but a stack trace should always be available.


Well, that's good news. I guess I'll just have to figure out how to look at
it - as I said I'm new at this. If one can have the function names in the
order they were called, I think one can always figure out what happened.
Nov 16 '05 #30

Funny, I just thought that shortly after sending the previous message.
Part of the issue is I'm new to Windows programming. Although I've read
Windows code (straight C versions of it), and done a couple of
kindergarten utilities in VB, I've only been doing real work in it for
about 6 months. Previously I worked [in tools and] with embedded systems
programming on special operating system that was probably much more simple
than Windows. Although the message loops looked similar, I think one can
get a much greater variety of messages, and from more different sources,
AND you're expected to deal with it with less training - which is why they
hide the details, eh?
The details of what's going on behind the scenese are hideously complex and
full of special cases. One big problem is that MS tries to be as backwardly
compatible as possible, and this means being compatible with some or all of
the stupid programmer tricks that were done 15 years ago. Some things are
done to be compatible with some original DOS code, early Win2.x and 3.x
code, etc. Nasty stuff. It's gotten a lot better but there's a lot of
baggage there. There are still people using DDE (Dynamic Data Exchange,
perhaps the worst communications protocol ever invented).

There are good reasons why they are promoting .NET - it's much easier to
learn to write good .NET code then it is to learn to write good Windows
code, either raw windows or using COM, MFC, or some other framework. It's
more consistent, both internally and externally, and you don't have to be
aware of the same amount of details. The amount of background "noise" that
must be in your head at all times when writing .net code is a lot less then
the amout of noise it takes to write vanilla windows code.

The good news is that the need to know what going on in windows behind the
scenes is decreasing, but it is still greater then zero. It would take
years and years to learn to write C windows programs (I've done it), and
there really is no need to do that.
. . .
I haven't worked out my strategy yet for Whidbey.
For what? Oh dear, I'm missing things again. Out of the loop as usual...


Whidbey what MSFT is calling their next release of .NET 2.0. It's got lots
of new features.
Hmmm, it may not be able to provide lines numbers and source file names,
but a stack trace should always be available.


Well, that's good news. I guess I'll just have to figure out how to look
at it - as I said I'm new at this. If one can have the function names in
the order they were called, I think one can always figure out what
happened.


If only it were that easy :-)

Nov 16 '05 #31

"David Levine" <no******************@wi.rr.com> wrote in message
news:uN**************@TK2MSFTNGP10.phx.gbl...
. . . The details of what's going on behind the scenese are hideously complex
and full of special cases.


Aren't they always? I remember a few years ago reading articles about how
skilled programmers would no longer be needed - there would be tools that
almost anyone could use to get their programming needs met. What nonsense.
The more people can do for themselves, the more they expect from us, and our
jobs never get much easier (good thing.)
. . .
There are good reasons why they are promoting .NET - it's much easier to
learn to write good .NET code then it is to learn to write good Windows
code, either raw windows or using COM, MFC, or some other framework.. . .


That I do believe. I really like C#, and most days I'm happy to work with
it. While I felt like I understood more by reading C windows code, it was
3.x (simpler back then I'm sure), and it's always easier to read than to
write. And even given that, my few attempts at reading MFC code left me
hopelessly confused ... I sincerely hope never to have to write any of it
:-)

... If one can have the function names in the order they were called, I
think one can always figure out what happened.


If only it were that easy :-)

Sh... don't tell me that. "Always" is probably too big a word for a newbie,
but in 6 years of programming, I've never had a problem I couldn't figure
out when I had a stack trace. And I have worked with some pretty complex
code (multi-process, of the infamous million+ line-of-code variety). Still,
if I tell you it could never happen it surely will tomorrow, so I guess I'd
better keep my mouth shut 8-)
Nov 16 '05 #32
I realize that there hasn't been any activity in this thread for a while. However, after making some modifications to my application based upon input that I received in this thread, I have noticed an interesting exception management-related behavior that I thought I would describe in order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason Clark on exception management, http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the following event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior: when exceptions are thrown from one form but handled from a different form, they end up being handled by the Application.ThreadException event handler rather than the intended exception handler on the other form. For example:

Consider that FormA attempts to launch FormB using the following code pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission to view formB");
}
}

Now, with the global exception handlers in place, if a security exception were thrown from within the FormB_Load() event handler, it will be handled from within the Application.ThreadException event handler rather than the catch block above. This causes the application to shut down, which is not the desired behavior.

Does this mean that when the global exception handler, Application.ThreadException, is in effect, no form can raise an exception that is handled by a different form??? Is the code above considered bad design for this reason???

Thanks for any thoughts!!!
Nov 16 '05 #33
I think the reason is a little different. I believe (though I have no direct proof of this other then observations I have made) that the windows.form class implements its own exception filter and handler around the entire form.

When the exception filter sees an exception it means that the application did not catch it, so in terms of the form, it is unhandled. It then checks to see if anyone has subscribed to the Application.ThreadException event, and if so, it catches the exception and fires the event. If not, it allows the exception to continue up the call stack. I believe you are seeing these behaviors because of this, and it makes a difference if you subscribe to the ThreadException prior to creating FormA versus subscribing to the event from within FormA.

If you register the Application.ThreadException and AppDomain.UnhandledException in your application's main I get similar (but not identical) behavior to what you describe. However, rather then use static methods that are registered in your application's Main routine, try making them instance methods of FormA. When I did that the catch handler in FormA always got the exception and neither UE handler ever saw it.

IMO the current implemenation of Application.ThreadException ought to be revised.

"craig" <e@mail.com> wrote in message news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while. However, after making some modifications to my application based upon input that I received in this thread, I have noticed an interesting exception management-related behavior that I thought I would describe in order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason Clark on exception management, http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the following event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior: when exceptions are thrown from one form but handled from a different form, they end up being handled by the Application.ThreadException event handler rather than the intended exception handler on the other form. For example:

Consider that FormA attempts to launch FormB using the following code pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission to view formB");
}
}

Now, with the global exception handlers in place, if a security exception were thrown from within the FormB_Load() event handler, it will be handled from within the Application.ThreadException event handler rather than the catch block above. This causes the application to shut down, which is not the desired behavior.

Does this mean that when the global exception handler, Application.ThreadException, is in effect, no form can raise an exception that is handled by a different form??? Is the code above considered bad design for this reason???

Thanks for any thoughts!!!
Nov 16 '05 #34
Craig,
The Application.ThreadException is raised as part of the Application.Run
method. The Application.Run method is the "message pump" that processes all
of the Win32 windows messages "converting" them into their respective
Windows Forms events.

I suspect Form.Load is the result of receiving the WM_CREATE Win32 windows
message.

In other words: Form.Show causes a Win32 window to be created which causes
the window to receive the WM_CREATE message, which gets "converted" into the
Form Load event. Seeing as the Application.Run method is dispatching the
WM_CREATE message, the exception in the Form Load event causes the
Application.ThreadException event.

Looking at
http://msdn.microsoft.com/netframewo...l/win32map.asp &
http://www.pinvoke.net/

Form.Show effectively does a Win32 ShowWindow.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while.
However, after making some modifications to my application based upon input
that I received in this thread, I have noticed an interesting exception
management-related behavior that I thought I would describe in order to try
to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason
Clark on exception management,
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the following
event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled
exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior:
when exceptions are thrown from one form but handled from a different form,
they end up being handled by the Application.ThreadException event handler
rather than the intended exception handler on the other form. For example:

Consider that FormA attempts to launch FormB using the following code
pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission to
view formB");
}
}

Now, with the global exception handlers in place, if a security exception
were thrown from within the FormB_Load() event handler, it will be handled
from within the Application.ThreadException event handler rather than the
catch block above. This causes the application to shut down, which is not
the desired behavior.

Does this mean that when the global exception handler,
Application.ThreadException, is in effect, no form can raise an exception
that is handled by a different form??? Is the code above considered bad
design for this reason???

Thanks for any thoughts!!!
Nov 16 '05 #35

"craig" <e@mail.com> wrote in message news:Ou**************@TK2MSFTNGP15.phx.gbl...
Thanks for the info, David. Sounds like you have spent alot of time tracking exception behavior relative to windows forms.

In your apps, do you often raise exceptions on one form, and then handle them on a different form?

I generally don't allow exceptions to escape from one form to be handled by another but there's no reason why that wouldn't work. As I said, make sure you register the ThreadException as an instance method of your first form.

If you wrap the FormB dialog in a try-catch and only register the AppDomain.UnhandledException I believe the problem you are having will go away - you wont get a UE and the exceptions will all be caught in the try-catch you have in FormA.
"David Levine" <no******************@wi.rr.com> wrote in message news:eG**************@TK2MSFTNGP10.phx.gbl...
I think the reason is a little different. I believe (though I have no direct proof of this other then observations I have made) that the windows.form class implements its own exception filter and handler around the entire form.

When the exception filter sees an exception it means that the application did not catch it, so in terms of the form, it is unhandled. It then checks to see if anyone has subscribed to the Application.ThreadException event, and if so, it catches the exception and fires the event. If not, it allows the exception to continue up the call stack. I believe you are seeing these behaviors because of this, and it makes a difference if you subscribe to the ThreadException prior to creating FormA versus subscribing to the event from within FormA.

If you register the Application.ThreadException and AppDomain.UnhandledException in your application's main I get similar (but not identical) behavior to what you describe. However, rather then use static methods that are registered in your application's Main routine, try making them instance methods of FormA. When I did that the catch handler in FormA always got the exception and neither UE handler ever saw it.

IMO the current implemenation of Application.ThreadException ought to be revised.

"craig" <e@mail.com> wrote in message news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while. However, after making some modifications to my application based upon input that I received in this thread, I have noticed an interesting exception management-related behavior that I thought I would describe in order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason Clark on exception management, http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the following event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior: when exceptions are thrown from one form but handled from a different form, they end up being handled by the Application.ThreadException event handler rather than the intended exception handler on the other form. For example:

Consider that FormA attempts to launch FormB using the following code pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission to view formB");
}
}

Now, with the global exception handlers in place, if a security exception were thrown from within the FormB_Load() event handler, it will be handled from within the Application.ThreadException event handler rather than the catch block above. This causes the application to shut down, which is not the desired behavior.

Does this mean that when the global exception handler, Application.ThreadException, is in effect, no form can raise an exception that is handled by a different form??? Is the code above considered bad design for this reason???

Thanks for any thoughts!!!
Nov 16 '05 #36
I believe he is having this problem because he subscribed to the
ThreadException from a static method (main) and not from an instance method
in FormA. At the time he subscribed there was no window at all in the
system, so perhaps the Forms class is getting confused about where to
deliver the event to. IOW, if there was no window or pump running at the
time the event was subscribed to it may getting confused - it may be
expecting an instance and there is none associated with the event.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uS*************@TK2MSFTNGP12.phx.gbl...
Craig,
The Application.ThreadException is raised as part of the Application.Run
method. The Application.Run method is the "message pump" that processes
all of the Win32 windows messages "converting" them into their respective
Windows Forms events.

I suspect Form.Load is the result of receiving the WM_CREATE Win32 windows
message.

In other words: Form.Show causes a Win32 window to be created which causes
the window to receive the WM_CREATE message, which gets "converted" into
the Form Load event. Seeing as the Application.Run method is dispatching
the WM_CREATE message, the exception in the Form Load event causes the
Application.ThreadException event.

Looking at
http://msdn.microsoft.com/netframewo...l/win32map.asp &
http://www.pinvoke.net/

Form.Show effectively does a Win32 ShowWindow.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while.
However, after making some modifications to my application based upon
input that I received in this thread, I have noticed an interesting
exception management-related behavior that I thought I would describe in
order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason
Clark on exception management,
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the following
event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled
exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior:
when exceptions are thrown from one form but handled from a different
form, they end up being handled by the Application.ThreadException event
handler rather than the intended exception handler on the other form. For
example:

Consider that FormA attempts to launch FormB using the following code
pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission to
view formB");
}
}

Now, with the global exception handlers in place, if a security exception
were thrown from within the FormB_Load() event handler, it will be handled
from within the Application.ThreadException event handler rather than the
catch block above. This causes the application to shut down, which is not
the desired behavior.

Does this mean that when the global exception handler,
Application.ThreadException, is in effect, no form can raise an exception
that is handled by a different form??? Is the code above considered bad
design for this reason???

Thanks for any thoughts!!!

Nov 16 '05 #37
David,
I believe he is having this problem because he subscribed to the
ThreadException from a static method (main) and not from an instance method
in FormA. Application.ThreadException is a static event! Remember events can be
instance or static, and their handlers can be instance or static. Events
really don't care either way, raising an Event simply calls all the handlers
(delegates) that have been registered with it...
At the time he subscribed there was no window at all in the system, so
perhaps the Forms class is getting confused about where to deliver the
event to. Again Application.ThreadException is a static event, it is "delivered" to
all the handlers that are currently registered with it.
if there was no window or pump running at the time the event was
subscribed to it may getting confused I'm really not sure why! The event (any event) is implemented as a Delegate,
Delegates really don't know any thing about windows or pumps.
it may be expecting an instance and there is none associated with the
event. Events don't expect instances, events expect handlers, these handlers can be
either instance methods or static methods, the event (more importantly the
underlying delegate) doesn't care what kind of method it (the delegate) is
associated with. Which IMHO is one of the truly cool & powerful features of
..NET events over COM & VB6 events!
I would expect the same result (as I described & Craig perceived) even if
LaunchFormB was called within a Form because of a Button Click event. In
fact that is the way I understand that Craig is calling it.

Hope this helps
Jay

"David Levine" <no******************@wi.rr.com> wrote in message
news:eC**************@TK2MSFTNGP10.phx.gbl...I believe he is having this problem because he subscribed to the
ThreadException from a static method (main) and not from an instance method
in FormA. At the time he subscribed there was no window at all in the
system, so perhaps the Forms class is getting confused about where to
deliver the event to. IOW, if there was no window or pump running at the
time the event was subscribed to it may getting confused - it may be
expecting an instance and there is none associated with the event.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uS*************@TK2MSFTNGP12.phx.gbl...
Craig,
The Application.ThreadException is raised as part of the Application.Run
method. The Application.Run method is the "message pump" that processes
all of the Win32 windows messages "converting" them into their respective
Windows Forms events.

I suspect Form.Load is the result of receiving the WM_CREATE Win32
windows message.

In other words: Form.Show causes a Win32 window to be created which
causes the window to receive the WM_CREATE message, which gets
"converted" into the Form Load event. Seeing as the Application.Run
method is dispatching the WM_CREATE message, the exception in the Form
Load event causes the Application.ThreadException event.

Looking at
http://msdn.microsoft.com/netframewo...l/win32map.asp &
http://www.pinvoke.net/

Form.Show effectively does a Win32 ShowWindow.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while.
However, after making some modifications to my application based upon
input that I received in this thread, I have noticed an interesting
exception management-related behavior that I thought I would describe in
order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason
Clark on exception management,
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the
following event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled
exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior:
when exceptions are thrown from one form but handled from a different
form, they end up being handled by the Application.ThreadException event
handler rather than the intended exception handler on the other form.
For example:

Consider that FormA attempts to launch FormB using the following code
pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission
to view formB");
}
}

Now, with the global exception handlers in place, if a security exception
were thrown from within the FormB_Load() event handler, it will be
handled from within the Application.ThreadException event handler rather
than the catch block above. This causes the application to shut down,
which is not the desired behavior.

Does this mean that when the global exception handler,
Application.ThreadException, is in effect, no form can raise an exception
that is handled by a different form??? Is the code above considered bad
design for this reason???

Thanks for any thoughts!!!


Nov 16 '05 #38
David,

I just tested your idea and it appears that your thinking is correct.
Previously, the entry point to my application looked as follows:

static void Main()
{
//CLR unhandled exceptions
AppDomain.CurrentDomain.UnhandledException +=new
UnhandledExceptionEventHandler(CurrentDomain_Unhan dledException);

//Windows forms unhandled exceptions
Application.ThreadException +=new
ThreadExceptionEventHandler(Application_ThreadExce ption);

Application.Run(new FormMain());
}

When the code is run in this configuration, an exception thrown from within
the FormB_Load() event handler is handled in the
Application_ThreadException() event handler rather than the catch block in
FormA as desired.

However, if I move the line of code which wires up the thread exception
event handler to the FormMain_Load() instance method as you suggested and
run the application, an exception thrown from within the FormB_Load() event
handler is handled in the catch block in FormA as desired.

I also tried moving this line of code to the FormMain constructor rather
than the FormMain_Load() event handler. In that case, the problem was not
corrected. It only seems to work from within the FormMain_Load() event
handler.

Thus, the new configuration looks as follows:

static void Main()
{
//CLR unhandled exceptions
AppDomain.CurrentDomain.UnhandledException +=new
UnhandledExceptionEventHandler(CurrentDomain_Unhan dledException);

Application.Run(new FormMain());
}

private void FormMain_Load(object sender, System.EventArgs e)
{
//Windows forms unhandled exceptions
Application.ThreadException +=new
ThreadExceptionEventHandler(Application_ThreadExce ption);
}

It would be interesting to determine exactly why this configuration works
and the other does not. Also, in this configuration, it would be
interesting to throw a ThreadException in order to see if it would be
handled in Application_ThreadException() as it should. Do you have any
thoughts regarding why the desired behavior is not acheived by placing the
line of code in the main form constructor??
"David Levine" <no******************@wi.rr.com> wrote in message
news:eC**************@TK2MSFTNGP10.phx.gbl...
I believe he is having this problem because he subscribed to the
ThreadException from a static method (main) and not from an instance method
in FormA. At the time he subscribed there was no window at all in the
system, so perhaps the Forms class is getting confused about where to
deliver the event to. IOW, if there was no window or pump running at the
time the event was subscribed to it may getting confused - it may be
expecting an instance and there is none associated with the event.

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:uS*************@TK2MSFTNGP12.phx.gbl...
Craig,
The Application.ThreadException is raised as part of the Application.Run
method. The Application.Run method is the "message pump" that processes
all of the Win32 windows messages "converting" them into their respective
Windows Forms events.

I suspect Form.Load is the result of receiving the WM_CREATE Win32
windows message.

In other words: Form.Show causes a Win32 window to be created which
causes the window to receive the WM_CREATE message, which gets
"converted" into the Form Load event. Seeing as the Application.Run
method is dispatching the WM_CREATE message, the exception in the Form
Load event causes the Application.ThreadException event.

Looking at
http://msdn.microsoft.com/netframewo...l/win32map.asp &
http://www.pinvoke.net/

Form.Show effectively does a Win32 ShowWindow.

Hope this helps
Jay
"craig" <e@mail.com> wrote in message
news:uP**************@TK2MSFTNGP15.phx.gbl...
I realize that there hasn't been any activity in this thread for a while.
However, after making some modifications to my application based upon
input that I received in this thread, I have noticed an interesting
exception management-related behavior that I thought I would describe in
order to try to get some of your thoughts.

Based upon the article in the June 2004 issue of MSDN magazine by Jason
Clark on exception management,
http://msdn.microsoft.com/msdnmag/issues/04/06/NET/, I added the
following event handlers to my application's Main() method:

1. AppDomain.CurrentDomain.UnhandledException (for CLR unhandled
exceptions)
2. Application.ThreadException (for windows forms unhandled exceptions)

Since I have dome this, however, I have noticed the following behavior:
when exceptions are thrown from one form but handled from a different
form, they end up being handled by the Application.ThreadException event
handler rather than the intended exception handler on the other form.
For example:

Consider that FormA attempts to launch FormB using the following code
pattern, with a sample exception handler:

private void LaunchFormB()
{
FormB formB = new FormB();
try
{
formB.Show();
}
catch(SecurityException ex)
{
MessageBox.Show("The authenticated user does not have permission
to view formB");
}
}

Now, with the global exception handlers in place, if a security exception
were thrown from within the FormB_Load() event handler, it will be
handled from within the Application.ThreadException event handler rather
than the catch block above. This causes the application to shut down,
which is not the desired behavior.

Does this mean that when the global exception handler,
Application.ThreadException, is in effect, no form can raise an exception
that is handled by a different form??? Is the code above considered bad
design for this reason???

Thanks for any thoughts!!!


Nov 17 '05 #39

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> wrote in message
news:u%****************@TK2MSFTNGP12.phx.gbl...
David,
I believe he is having this problem because he subscribed to the
ThreadException from a static method (main) and not from an instance
method in FormA. Application.ThreadException is a static event! Remember events can be
instance or static, and their handlers can be instance or static. Events
really don't care either way, raising an Event simply calls all the
handlers (delegates) that have been registered with it...


I know about the differences between static and instance delegates. However,
this is not a question about how delegates are implemented, it is a question
about how the Forms class handles exceptions occurring on that one thread
and when it actually fires the event. I haven't spent a lot of time digging
into the internals but it is not straightforward. The Forms class, and how
it handles threads, looks like a bit of black art.
At the time he subscribed there was no window at all in the system, so
perhaps the Forms class is getting confused about where to deliver the
event to. Again Application.ThreadException is a static event, it is "delivered" to
all the handlers that are currently registered with it.


That affects to whom the event is delivered, (static versus instance
methods), not how it is generated in the first place.

if there was no window or pump running at the time the event was
subscribed to it may getting confused

I'm really not sure why! The event (any event) is implemented as a
Delegate, Delegates really don't know any thing about windows or pumps.


Agreed.
it may be expecting an instance and there is none associated with the
event. Events don't expect instances, events expect handlers, these handlers can
be either instance methods or static methods, the event (more importantly
the underlying delegate) doesn't care what kind of method it (the
delegate) is associated with.


I was not referring to the delegate itself, but the code that determined
whether or not to fire the event.



I would expect the same result (as I described & Craig perceived) even if
LaunchFormB was called within a Form because of a Button Click event. In
fact that is the way I understand that Craig is calling it.


We are talking apples and oranges. The real question is: under what
circumstances will the Forms class catch an exception and forward it to the
Application.ThreadException event, and when will it allow other mechanisms
to handle it. Once the Forms class actually fires the ThreadException
everything works as you describe, but the problem is that it is never firing
in the first place.

regards,
Dave


Nov 17 '05 #40

"craig" <e@mail.com> wrote in message
news:Ox**************@tk2msftngp13.phx.gbl...
David,

I just tested your idea and it appears that your thinking is correct.
Good.
<snip>
When the code is run in this configuration, an exception thrown from
within the FormB_Load() event handler is handled in the
Application_ThreadException() event handler rather than the catch block in
FormA as desired.

However, if I move the line of code which wires up the thread exception
event handler to the FormMain_Load() instance method as you suggested and
run the application, an exception thrown from within the FormB_Load()
event handler is handled in the catch block in FormA as desired.

I also tried moving this line of code to the FormMain constructor rather
than the FormMain_Load() event handler. In that case, the problem was not
corrected. It only seems to work from within the FormMain_Load() event
handler.
It appears that it wants to be associated with a Form object and is not
really designed to operate otherwise. It might also need a functioning
message pump at the time the event is subscribed to, which may be why
subscribing to it in the ctor does not work (this is another WAG). On the
whole, I'd call this one a bug - it certainly doesn't work in a reasonable
manner, and it is clearly not documented about any restrictions regarding
when or how to subscribe to the event.

<snip> It would be interesting to determine exactly why this configuration works
and the other does not. Also, in this configuration, it would be
interesting to throw a ThreadException in order to see if it would be
handled in Application_ThreadException() as it should. Do you have any
thoughts regarding why the desired behavior is not acheived by placing the
line of code in the main form constructor??


Yes, it's called a "bug" and MSFT needs to fix it! All we can do is work
around it and avoid the problem.

There are several places in the CLR where you can subscribe to an event and
nothing will ever happen. One such is when subscribing to the
UnhandledException event...if the code is not running in the default
appdomain then the event will never get delivered - it only works in the
default appdomain. There are several other cases like this that slip my mind
at the moment.

In my opinion if the event itself can determine that the subscription will
not perform as expected it ought to throw an exception or otherwise signal
that even though mechanically the subscriber is connected to the event, the
event itself will never get delivered. Otherwise you have the worst of all
possible worlds - the illusion that something works. The code will pass a
code review and never detect a problem, but it simply will not work.

regards,
Dave
Nov 17 '05 #41
Thanks again, David. I can't tell you how much I appreciate your taking the
time to describe this work-around.

I wonder if it wouldn't make sense to pass this info on to Jason Clark, the
guy who wrote the MSDN article on global exception handling.

"David Levine" <no******************@wi.rr.com> wrote in message
news:uS**************@tk2msftngp13.phx.gbl...

"craig" <e@mail.com> wrote in message
news:Ox**************@tk2msftngp13.phx.gbl...
David,

I just tested your idea and it appears that your thinking is correct.


Good.
<snip>
When the code is run in this configuration, an exception thrown from
within the FormB_Load() event handler is handled in the
Application_ThreadException() event handler rather than the catch block
in FormA as desired.

However, if I move the line of code which wires up the thread exception
event handler to the FormMain_Load() instance method as you suggested and
run the application, an exception thrown from within the FormB_Load()
event handler is handled in the catch block in FormA as desired.

I also tried moving this line of code to the FormMain constructor rather
than the FormMain_Load() event handler. In that case, the problem was
not corrected. It only seems to work from within the FormMain_Load()
event handler.


It appears that it wants to be associated with a Form object and is not
really designed to operate otherwise. It might also need a functioning
message pump at the time the event is subscribed to, which may be why
subscribing to it in the ctor does not work (this is another WAG). On the
whole, I'd call this one a bug - it certainly doesn't work in a reasonable
manner, and it is clearly not documented about any restrictions regarding
when or how to subscribe to the event.

<snip>
It would be interesting to determine exactly why this configuration works
and the other does not. Also, in this configuration, it would be
interesting to throw a ThreadException in order to see if it would be
handled in Application_ThreadException() as it should. Do you have any
thoughts regarding why the desired behavior is not acheived by placing
the line of code in the main form constructor??


Yes, it's called a "bug" and MSFT needs to fix it! All we can do is work
around it and avoid the problem.

There are several places in the CLR where you can subscribe to an event
and nothing will ever happen. One such is when subscribing to the
UnhandledException event...if the code is not running in the default
appdomain then the event will never get delivered - it only works in the
default appdomain. There are several other cases like this that slip my
mind at the moment.

In my opinion if the event itself can determine that the subscription will
not perform as expected it ought to throw an exception or otherwise signal
that even though mechanically the subscriber is connected to the event,
the event itself will never get delivered. Otherwise you have the worst of
all possible worlds - the illusion that something works. The code will
pass a code review and never detect a problem, but it simply will not
work.

regards,
Dave

Nov 17 '05 #42
By the way....I was just wondering if you have any kind of a .NET weblog
that I could check out??

"David Levine" <no******************@wi.rr.com> wrote in message
news:uS**************@tk2msftngp13.phx.gbl...

"craig" <e@mail.com> wrote in message
news:Ox**************@tk2msftngp13.phx.gbl...
David,

I just tested your idea and it appears that your thinking is correct.


Good.
<snip>
When the code is run in this configuration, an exception thrown from
within the FormB_Load() event handler is handled in the
Application_ThreadException() event handler rather than the catch block
in FormA as desired.

However, if I move the line of code which wires up the thread exception
event handler to the FormMain_Load() instance method as you suggested and
run the application, an exception thrown from within the FormB_Load()
event handler is handled in the catch block in FormA as desired.

I also tried moving this line of code to the FormMain constructor rather
than the FormMain_Load() event handler. In that case, the problem was
not corrected. It only seems to work from within the FormMain_Load()
event handler.


It appears that it wants to be associated with a Form object and is not
really designed to operate otherwise. It might also need a functioning
message pump at the time the event is subscribed to, which may be why
subscribing to it in the ctor does not work (this is another WAG). On the
whole, I'd call this one a bug - it certainly doesn't work in a reasonable
manner, and it is clearly not documented about any restrictions regarding
when or how to subscribe to the event.

<snip>
It would be interesting to determine exactly why this configuration works
and the other does not. Also, in this configuration, it would be
interesting to throw a ThreadException in order to see if it would be
handled in Application_ThreadException() as it should. Do you have any
thoughts regarding why the desired behavior is not acheived by placing
the line of code in the main form constructor??


Yes, it's called a "bug" and MSFT needs to fix it! All we can do is work
around it and avoid the problem.

There are several places in the CLR where you can subscribe to an event
and nothing will ever happen. One such is when subscribing to the
UnhandledException event...if the code is not running in the default
appdomain then the event will never get delivered - it only works in the
default appdomain. There are several other cases like this that slip my
mind at the moment.

In my opinion if the event itself can determine that the subscription will
not perform as expected it ought to throw an exception or otherwise signal
that even though mechanically the subscriber is connected to the event,
the event itself will never get delivered. Otherwise you have the worst of
all possible worlds - the illusion that something works. The code will
pass a code review and never detect a problem, but it simply will not
work.

regards,
Dave

Nov 17 '05 #43

"craig" <e@mail.com> wrote in message
news:eg*************@TK2MSFTNGP09.phx.gbl...
Thanks again, David. I can't tell you how much I appreciate your taking
the time to describe this work-around.

I wonder if it wouldn't make sense to pass this info on to Jason Clark,
the guy who wrote the MSDN article on global exception handling.


I appreciate the thought but I've found that unsolicited advice is usually
the worst kind to give. But thanks.

And in response to your other message, I just started a weblog recently -
haven't done much with it yet but here it is anway...
http://wiscdave.blogspot.com/
Nov 17 '05 #44
Wow....the list of discussion topics on your blog looks excellent. I am
looking forward to reading...

Thanks again, Dave.

"David Levine" <no******************@wi.rr.com> wrote in message
news:uu*************@TK2MSFTNGP10.phx.gbl...

"craig" <e@mail.com> wrote in message
news:eg*************@TK2MSFTNGP09.phx.gbl...
Thanks again, David. I can't tell you how much I appreciate your taking
the time to describe this work-around.

I wonder if it wouldn't make sense to pass this info on to Jason Clark,
the guy who wrote the MSDN article on global exception handling.


I appreciate the thought but I've found that unsolicited advice is usually
the worst kind to give. But thanks.

And in response to your other message, I just started a weblog recently -
haven't done much with it yet but here it is anway...
http://wiscdave.blogspot.com/

Nov 17 '05 #45

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1826
by: Steve O'maley | last post by:
I currently have the Exception Management Application Block working in my base directory, but when I create pages in a subfolder the Exception Management Application Block is never executed. The...
1
1829
by: Abelardo Vacca | last post by:
Hello, I am currently in the process of switching our application to a N-Tier model with .NET. One of the aspects we want ot get right from the start not to worry about it after is the...
6
2100
by: Páll Ólafsson | last post by:
Hi I have a problem with the Microsoft.ApplicationBlocks.ExceptionManagement? I can't get it to work in RELEASE mode? If I run the project in debug mode the block works fine but when I run the...
3
5014
by: Scott Brady Drummonds | last post by:
Hi, all, I've a fairly small piece of code that is causing me problems. I'm using std::string and am building a string of several dozen characters using several of std::string's functions: a...
5
5802
by: PCC | last post by:
I am using the Exception Managment Application Block on Windows Server 2003 Enterprise and .NET v1.1. If I use the block with an ASP.NET web wervice or in a web application I get the following...
1
1396
by: leodippolito | last post by:
Hello, I have these entities in my ASP.NET application: - data access layer (DATA) - custom exception class (EXCEPTION) - cache management class (CACHE) They're all built into different...
1
3374
by: SQLJunkie | last post by:
Hi, I have installed SQL 2005 RTM on a new server and I keep getting this error (described below) quite frequently. Was wondering if anyone has a clue on what's happening here. I tried googling...
2
2228
by: KaNos | last post by:
Hello world, I've made a webservice (c# v2) to install in a server IIS 6 on a Windows 2000 last SP. We can use the webservice in local, throw the pages wich present the methods, with a windows...
0
7063
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7313
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6970
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7441
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5558
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
4987
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3156
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3146
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
720
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.