.Net Exceptions

G

Guest

Is there any way to find out if a particular .net function will throw an
exception without first generating the exception?

I am using structured exception handling i.e. try catch finally blocks with
a top level catch all for Exception. However, I would like to be able to
catch most .net exceptions when they are generated. I would then be able to
generate a valuable exception message and do something about it!!! Hence the
question above.

If anyone would like to talk about their preferred exception handling
methodology I am all ears.

Thanks,
Mark
 
M

Morten Wennevik

Hi mag31,

To my knowledge, unless the exception is documented somewhere, or you have access to the original source to see what exceptions that method may throw, you have to resort to a general exception catching, catch(Exception ex).
 
G

Guest

Thank you Morten, that answers my question, obviously not with the answer I
want :-(

Mark
 
C

cody

Imho, .NET has a very stupid exception model. There is not way telling which
exceptions can be thrown by a specifiy method. Also the Exception hirarchy
seems not to be well designed.

Lots of people keep telling you that using catch (Exception) is bad style
and you should always catch specific exception Iam the opinion that in some
places is the the best method. Especially when calling third party
components or wrapped winapi stuff like Process.Start or creating Database
connections, you never know which kind of exception can be thrown.
Even if exceptions are documented there a chance that something was
forgotten to document or in a later version a new exception is thrown in
that component or maybe you forget to catch one specific exception.

Sure, if you call int.Parse() you will certainly only catch FormatException
or when reading from a file there will nothing else be thrown except
IOException. But as I said sometimes its better to catch System.Exception,
just to be sure.
 
J

Joerg Jooss

cody said:
Imho, .NET has a very stupid exception model. There is not way
telling which exceptions can be thrown by a specifiy method. Also the
Exception hirarchy seems not to be well designed.

I disagree on the model part, but regarding the hierarchy you're right.
What's really missing is a distinction between potentially recoverable
conditions and irrecoverable failures -- lo and behold, that's what
Exception and Error in Java represent. In defense of MS, getting an
excpetion hierarchy right is incredibly hard -- but since they borrowed so
many good things from Java, they should taken that part as well ;-)

And this is not the same as the SystemException vs. ApplicationException
approach, which doesn't cut it anyway.
Lots of people keep telling you that using catch (Exception) is bad
style and you should always catch specific exception Iam the opinion
that in some places is the the best method.

No. When you say catch (Exception) you think it means:

"This stupid API isn't properly documented, so I need to be sure."

But what it means is

"I can handle it."

Unfortunately, nothing could more mistaken. Depending on the failure, you
may hide or swallow a severe problem. Of course that's caused by the missing
distinction between Error and Exception. But save for a global "log and
die/abort" exception handler, there's little you can do with catch
(Exception).
Especially when calling
third party components or wrapped winapi stuff like Process.Start or
creating Database connections, you never know which kind of exception
can be thrown.

Can you give an example?
Even if exceptions are documented there a chance that something was
forgotten to document or in a later version a new exception is thrown
in that component or maybe you forget to catch one specific exception.

First, hopefully nobody drops an updated library in production without prior
testing. Grab the library, run your unit tests (which hopefully cover both
normal and exptected error conditions), and check the green light. If your
development process doesn't include this very basic step, you're in trouble
anyway...
Sure, if you call int.Parse() you will certainly only catch
FormatException or when reading from a file there will nothing else
be thrown except IOException. But as I said sometimes its better to
catch System.Exception, just to be sure.

To be sure of what ;-)

Cheers,
 
C

cody

Imho, .NET has a very stupid exception model. There is not way
I disagree on the model part, but regarding the hierarchy you're right.
What's really missing is a distinction between potentially recoverable
conditions and irrecoverable failures -- lo and behold, that's what
Exception and Error in Java represent. In defense of MS, getting an
excpetion hierarchy right is incredibly hard -- but since they borrowed so
many good things from Java, they should taken that part as well ;-)

And this is not the same as the SystemException vs. ApplicationException
approach, which doesn't cut it anyway.


No. When you say catch (Exception) you think it means:

"This stupid API isn't properly documented, so I need to be sure."

But what it means is

"I can handle it."

Yes indeed. If I try to start a process with Process.Start() and an
exception occures who cares what kind of error it was? I display a
messagebox and inform the user what happens and display the message from the
exception.
The same is true when trying to open a Database connection or calling a
method which loads a specific file.
The most stupid thing one could do is to catch every exception type that
could possibly occur in an endless stack of catch clauses, each of them
doing the same thing: informing the user and displaying the message of the
exception.
And at the end, an undocumented exception occures which never occured during
testing because it occures because of a wrong driver or similar and this
lets the whole application crash, just because you were soo sure that only
the documented exceptions could occur..
Unfortunately, nothing could more mistaken. Depending on the failure, you
may hide or swallow a severe problem. Of course that's caused by the missing
distinction between Error and Exception. But save for a global "log and
die/abort" exception handler, there's little you can do with catch
(Exception).


Can you give an example?

You would let your application totally crash just because you third party
sound library throws a funny exception when you tried to play background
sound but the user does have funny hardware which lets the soundcomponent
totally crash. Will you really trust every third party component? You never
should.
Nobody cares wheather the stupid background sounds works or not. But if your
programm crashes because of that you're the stupid.

We *can* trust our own code, sure. But we cannot trust 3rd party components
as we do not have their sourcecode.
 
D

David Levine

I disagree on the model part, but regarding the hierarchy you're right.
What's really missing is a distinction between potentially recoverable
conditions and irrecoverable failures -- lo and behold, that's what
Exception and Error in Java represent.

It isn't at all clear to me how a component that throws an exception can
determine if something is recoverable or not - perhaps there are times it
can, but there are more cases where only a higher-level module can make that
decision.
And this is not the same as the SystemException vs. ApplicationException
approach, which doesn't cut it anyway.

Agreed. On the surface it would be useful to have categories such as
SystemFatalException, SystemCriticalException, but then this opens a
different can of worms - the ability to recover or not from an exception is
application dependent unless the runtime has become corrupted and is about
to shutdown.
No. When you say catch (Exception) you think it means:

"This stupid API isn't properly documented, so I need to be sure."

But what it means is

"I can handle it."

Unfortunately, nothing could more mistaken. Depending on the failure, you
may hide or swallow a severe problem. Of course that's caused by the missing
distinction between Error and Exception. But save for a global "log and
die/abort" exception handler, there's little you can do with catch
(Exception).

I have come to use something like this...

catch(SomeSpecificException sse)
{
// recover/retry/whatever
}
catch(Exception ex)
{
throw new CloneExceptionType(ex,"Add some context info here."); // or
throw some other type
}

....and kick it upstairs for high-level code to deal with. Ultimately it
boils down to 2 basic choices - either the code knows how to recover from an
exception or it doesn't. If it doesn't, then you can either allow the user
to retry/cancel/abort the operation, or you can exit the application.

First, hopefully nobody drops an updated library in production without prior
testing. Grab the library, run your unit tests (which hopefully cover both
normal and exptected error conditions), and check the green light. If your
development process doesn't include this very basic step, you're in trouble
anyway...

I kind of disagree here; I use unit testing and it is a valuable
tool/technique but sometimes all it does is validate our own misconceptions.
It will not force a third-party component to throw exceptions, especially
ones that you did not know could be thrown - if it did then you are really
writing a unit test that validates the component, not your own code. A unit
test would probably create a mock object for the library/component. I think
testing an external component used by your code is more of a systems test
then a unit test.

One problem is how a system evolves over time. Even if you nail it and
handle every specific exception in the original code base, as it evolves and
as components change there is no way to prevent them from throwing exception
types different then those thrown in the original implementation. A robust
system must have some way of dealing with new/unexpected error conditions,
and this forces it to catch and deal with the generic Exception type.
 
J

Joerg Jooss

cody said:
Yes indeed. If I try to start a process with Process.Start() and an
exception occures who cares what kind of error it was? I display a
messagebox and inform the user what happens and display the message
from the exception.

Which depending on the exception may not work.
The same is true when trying to open a Database connection or calling
a method which loads a specific file.
The most stupid thing one could do is to catch every exception type
that could possibly occur in an endless stack of catch clauses, each
of them doing the same thing: informing the user and displaying the
message of the exception.
And at the end, an undocumented exception occures which never occured
during testing because it occures because of a wrong driver or
similar and this lets the whole application crash, just because you
were soo sure that only the documented exceptions could occur..

Again, you're assuming that this is recoverable situation. But in truth, you
don't know if an unexpected exception is recoverable. Also, I don't see the
benefit of an error message saying: "Oops. Dunno what happened, but we'll
continue for now. Stay tuned." A better approach to me is
terminate-and-restart, like the way newer MS Office applications behave.
You would let your application totally crash just because you third
party sound library throws a funny exception when you tried to play
background sound but the user does have funny hardware which lets the
soundcomponent totally crash. Will you really trust every third party
component? You never should.

Again, you only know that *afterwards*, when analyzing a stacktrace. At
runtime, all you can do is keep fingers crossed. A third party library
should not throw "funny" exceptions, but expose a properly designed
exception hierarchy -- otherwise it may do more harm than good.

[...]
We *can* trust our own code, sure. But we cannot trust 3rd party
components as we do not have their sourcecode.

That's probably the propert way to look at it from a security perspective,
but from an OO point of view that won't work. Either an exception is part of
a component's accessible API or not. If not, it is an implementation detail
you should not deal with. And can we trust our own code? No. Even our own
code can throw way more exceptions we'll ever be able to handle.

Cheers,
 
C

cody

Yes indeed. If I try to start a process with Process.Start() and an
Which depending on the exception may not work.

Sure if depends on the component. If it is one of my examples catching all
will work and doesn't cause any problems.
If it throws a fatal exception like stackoverflow, we cannot do anything
anyway since it is rethrown automatically, as are other fatal exceptions
too. Here again is the problem: There is not way telling: do not catch such
fatal exceptions. The .NET exception model is inherently broken. If there
would be at least a property in System.Exception to determine wheather I can
catch that Exception or not, it would be very helpful.
Again, you're assuming that this is recoverable situation. But in truth, you
don't know if an unexpected exception is recoverable. Also, I don't see the
benefit of an error message saying: "Oops. Dunno what happened, but we'll
continue for now. Stay tuned." A better approach to me is
terminate-and-restart, like the way newer MS Office applications behave.

What is the problem? Fact is that database could not be opened. May it due
to a security issue, an IO-Error, a corrupted database, a denied conection,
a wrong IP or port or driver. Fact is you tell the user why the connection
could not established and tell them to try another database.
Why should we let the whole application crash? If your programs are like
that, I hope I do not need to use them..
Why do you want the whole app to shut down only because "an unknown
exception" occured during connection with the database?
Again, you only know that *afterwards*, when analyzing a stacktrace. At
runtime, all you can do is keep fingers crossed. A third party library
should not throw "funny" exceptions, but expose a properly designed
exception hierarchy -- otherwise it may do more harm than good.

What it should or not is clear, but nevertheless they *can* do it, and you
*cannot* do anything against it.
When your customer comes to you and tells you that your app crashed simply
because of an unknown exception
in a unimportant component of your app crash will you tell them: "oh, but it
should not throw these funny exceptions and therefore I didn't catch them."
That's probably the propert way to look at it from a security perspective,
but from an OO point of view that won't work. Either an exception is part of
a component's accessible API or not.

The problem is that in .NET unlike java an exception is not part of the
public API.
You can try to document them, but that all you can do: trying it.
If not, it is an implementation detail you should not deal with.

Sure. Let the whole app crash because I should not deal with that exception.

Let me give another example. You have an interface which represents a
database exception. Then you have a method which returns a database
connection (a class which implements that interface).
This database could base upon a network connection, a text file, an excel
file, or it may use remoting.
Sure you can document everything but if somewhere in your exception hirarchy
an exception occures which is not documented you will let you whole app die.
And can we trust our own code? No. Even our own
code can throw way more exceptions we'll ever be able to handle.

In our own code we know which exceptions we throw, we properly document them
and we have strong conventions.
 
J

Joerg Jooss

David said:
It isn't at all clear to me how a component that throws an exception
can determine if something is recoverable or not - perhaps there are
times it can, but there are more cases where only a higher-level
module can make that decision.

In Java, Errors are (to be) only thrown by the JVM. Don't confuse
recoverable with being able to handle. If a component throws an Exception,
it obviously cannot handle it -- but the situation can be recovered from.
Agreed. On the surface it would be useful to have categories such as
SystemFatalException, SystemCriticalException, but then this opens a
different can of worms - the ability to recover or not from an
exception is application dependent unless the runtime has become
corrupted and is about to shutdown.

That's why I'd like to see a different exception family that doesn't blur
the lines between a fatal system failure and some recoverable exception.

[...]
I have come to use something like this...

catch(SomeSpecificException sse)
{
// recover/retry/whatever
}
catch(Exception ex)
{
throw new CloneExceptionType(ex,"Add some context info here."); // or
throw some other type
}

...and kick it upstairs for high-level code to deal with. Ultimately
it boils down to 2 basic choices - either the code knows how to
recover from an exception or it doesn't. If it doesn't, then you can
either allow the user to retry/cancel/abort the operation, or you can
exit the application.

Unfortunately, this could mask an OutOfMemoryException or other terrible
things if the newly thrown exception type is not explicitly meant to be
fatal.
I kind of disagree here; I use unit testing and it is a valuable
tool/technique but sometimes all it does is validate our own
misconceptions. It will not force a third-party component to throw
exceptions, especially ones that you did not know could be thrown -
if it did then you are really writing a unit test that validates the
component, not your own code. A unit test would probably create a
mock object for the library/component. I think testing an external
component used by your code is more of a systems test then a unit
test.

It probably depends on the level of integration that is covered by the test.
A facade that wraps technical exceptions in business interface exceptions
certainly requires such coverage at the unit level.

One problem is how a system evolves over time. Even if you nail it
and handle every specific exception in the original code base, as it
evolves and as components change there is no way to prevent them from
throwing exception types different then those thrown in the original
implementation. A robust system must have some way of dealing with
new/unexpected error conditions, and this forces it to catch and deal
with the generic Exception type.

I still don't see how ignoring or hiding potentially fatal errors
contributes to robustness. The FCL also provides several callbacks that
allow to be notified of unhandled errors.

Cheers,
 
J

Joerg Jooss

cody wrote:
[...]
What is the problem? Fact is that database could not be opened. May
it due to a security issue, an IO-Error, a corrupted database, a
denied conection, a wrong IP or port or driver. Fact is you tell the
user why the connection could not established and tell them to try
another database.

You seem to have a very specific application im mind. Unfortunately, in many
applications selecting another database is not an option. And the whole
sample seems a bit contrived to me. You're not telling me that you handle
database errors by catch (Exception)?
Why should we let the whole application crash? If your programs are
like that, I hope I do not need to use them..
Why do you want the whole app to shut down only because "an unknown
exception" occured during connection with the database?

It's not about letting an application deliberately crash. It's about
avoiding more fatal errors and potential damage to user data as early as
possible.
What it should or not is clear, but nevertheless they *can* do it,
and you *cannot* do anything against it.

Yeah, sure. I guess they won't complain when you say "no thanks" the next
time they try to sell you a component.
When your customer comes to you and tells you that your app crashed
simply because of an unknown exception
in a unimportant component of your app crash will you tell them: "oh,
but it should not throw these funny exceptions and therefore I didn't
catch them."

You seem to have quite knowledgeable customers ;-)
Again, you're reasoning is based on the flawed assumption you can do
something meaningful with catch (Exception). Just thinking of
OutOfMemoryException, ExecutionEngineException, or StackOverflowException, I
tend to disagree.
The problem is that in .NET unlike java an exception is not part of
the public API.

It is. The compiler cannot enforce it, but it is.
You can try to document them, but that all you can do: trying it.

Sure. Let the whole app crash because I should not deal with that
exception.

Again, you're confusing crashing with safely aborting. That does not
necessarily imply termination.
Let me give another example. You have an interface which represents a
database exception. Then you have a method which returns a database
connection (a class which implements that interface).
This database could base upon a network connection, a text file, an
excel file, or it may use remoting.
Sure you can document everything but if somewhere in your exception
hirarchy an exception occures which is not documented you will let
you whole app die.


In our own code we know which exceptions we throw, we properly
document them and we have strong conventions.

You know what your code *explicitly* throws.

Cheers,
 
C

cody

It's not about letting an application deliberately crash. It's about
avoiding more fatal errors and potential damage to user data as early as
possible.

I don't talk about exceptions in my application, Iam talking about 3rd party
components.
If that component throws I know that something is wrong with that component
but this doesn't nessarily mean that my app is in trouble.

If my code, which really deals with user data throws an unknown exception,
in that case my app is in trouble and I'll vertainly not catch
System.Exception, instead shut it down and inform the use about the reason.
Again, you're reasoning is based on the flawed assumption you can do
something meaningful with catch (Exception). Just thinking of
OutOfMemoryException, ExecutionEngineException, or StackOverflowException, I
tend to disagree.

That is the whole problem with the .NET exception model. You cannot tell
wheather an exception is critical or not. If you catch one of them, the are
automatically rethrown which means the MessageBox which should inform the
user is displayed and later the global handler will also catch the same
exception and will display a message again.
Yeah, sure. I guess they won't complain when you say "no thanks" the next
time they try to sell you a component.

Yes next time. After the Customer decides not to buy your app because it
crashed just because an unimportant library you used didn't work properly
and threw an unexpected exception.
Again, you're confusing crashing with safely aborting. That does not
necessarily imply termination.

in my knowledge there is no much difference between aborting and
termination.
 
J

Joerg Jooss

cody said:
I don't talk about exceptions in my application, Iam talking about
3rd party components.
If that component throws I know that something is wrong with that
component but this doesn't nessarily mean that my app is in trouble.

An unhandled exception thrown in third party component is an exception in
your application. If you expect the exception, then you're not in trouble.
But the whole discussion is about blindly handling unknown (i.e. unexpected)
exceptions.
If my code, which really deals with user data throws an unknown
exception, in that case my app is in trouble and I'll vertainly not
catch System.Exception, instead shut it down and inform the use about
the reason.

So we actually agree...
That is the whole problem with the .NET exception model. You cannot
tell wheather an exception is critical or not.

(I wouldn't call it the model -- it's the exception hierarchy.)
If you catch one of
them, the are automatically rethrown which means the MessageBox which
(Huh?)

should inform the user is displayed and later the global handler will
also catch the same exception and will display a message again.

.... and end up at looking back at Java's Error vs Exception distinction.
Yes next time. After the Customer decides not to buy your app because
it crashed just because an unimportant library you used didn't work
properly and threw an unexpected exception.

It's just that the unimportant library (if it's unimportant, why is it in
there anyway?) might throw OutOfMemoryException. And what will your customer
tell you if your app crashes at later point in time and users lose data,
only because you swallowed a fatal error?
in my knowledge there is no much difference between aborting and
termination.

Read again: *Safely* aborting. Logging. Office-style restarting. Overwriting
security sensitive data in memory (unmanaged code). Sending notifications.

Cheers,
 
D

David Levine

In Java, Errors are (to be) only thrown by the JVM. Don't confuse
recoverable with being able to handle. If a component throws an Exception,
it obviously cannot handle it -- but the situation can be recovered from.
That still does not strike me as a distinction that is always meaningful;
see below for more. Also, I prefer to not get into an argument about JAVA
and .net - frankly, I don't care what java does. If you wish to propose
changing the .net model then please do so without muddying the discussion
with a comparison of .net versus java.
That's why I'd like to see a different exception family that doesn't blur
the lines between a fatal system failure and some recoverable exception.
My perspective is that there is only a single exception that should always
be fatal - ExecutionEngineException - and that is because the runtime itself
has become corrupted; I regard this exception as a form of CLR
self-diagnostic exception.

All other exceptions could be handled by the application, including
StackOverflow, OutOfMemory, etc. The fact that today these are fatal (the
runtime shuts down) does not mean that they always should be fatal. A
managed host ought to be able to establish an secure execution environment
for managed executables/components, perhaps in a secondary appdomain, and a
part of that environment ought to be policies on how these exceptions are
handled. A stack overflow on a manual thread ought to kill the thread but
not necessarily shutdown the entire application; same for OOM. It may
require the appdomain to be unloaded, but it should not require the entire
managed application to terminate.

Unfortunately, this could mask an OutOfMemoryException or other terrible
things if the newly thrown exception type is not explicitly meant to be
fatal.

It would not be masked. The original exception is preserved as the inner
exception, and the same type could be rethrown if that was the intended
effect. Also, the distinction between what is fatal and what is recoverable
is application-dependent.

I once tried to come up with a table of exceptions that were fatal versus
recoverable and add that to my exception handling, but after testing it I
gave up. The reason was simple - if the exception truly is fatal the runtime
will shutdown regardless of what your exception handler does. Typically your
handler will never even get called - the runtime shuts itself down
immediately. This behavior may change in the future and if it does I will
revisit this issue.

This is an area of the runtime that is extremely poorly documented, probably
because the implementation is rapidly changing. If MSFT ever documents the
behavior I can code for it, but until then it seems pointless to try to
second guess the runtime.

It probably depends on the level of integration that is covered by the test.
A facade that wraps technical exceptions in business interface exceptions
certainly requires such coverage at the unit level.

re: the manner of unit testing code - a layer that wraps-rethrows
exceptions - is to create a mock object and have a specific test method in
the mock object throw a specific exception that your own code handles. The
unit test invokes a method in your code that calls into the mock object, not
the actual third-party library. The mock object throws the exception and
your code is supposed to deal with it. The unit test code then verifies that
your code did the right thing with it (whatever the "right thing" is
supposed to do).

At no time was the actual 3rd party library invoked; the test will not test
the 3rd party library for new exception types that it might throw.
Therefore it cannot detect changes to the library.

If your test requires your code to actually make calls into the 3rd party
lib then it is not a unit test, it is a system test. They are not the same
thing.

I still don't see how ignoring or hiding potentially fatal errors
contributes to robustness.

In no case were fatal errors hidden or ignored - that is your own
interpretation, and one that is not always correct. It may be true for your
own application that any unhandled exception is fatal, but that is not
universal for all applications.
The FCL also provides several callbacks that
allow to be notified of unhandled errors.
I am aware of that. I regard all UEs as bugs. IMO all exceptions should be
caught and dealt with somewhere. Third party libs represent a particularly
nasty set of problems because they can start threads themselves and not
catch the exceptions thrown on that hidden thread. This will result in a UE
that cannot be caught by wrapping the thread that the library is invoked on.
The supplier of the lib should be notified of the problem so they can fix
it, but the application still needs to deal with it. In this case the system
response should be under the control of the application -
abort/retry/continue/terminate are all valid responses.
 
C

cody

If you catch one of them, the are automatically rethrown which means the
MessageBox which

Fatal exceptions like StackOverflow cannot actually caught. If you catch
them, they will rethrow automatically at the end of the catch block.
It's just that the unimportant library (if it's unimportant, why is it in
there anyway?) might throw OutOfMemoryException. And what will your customer
tell you if your app crashes at later point in time and users lose data,
only because you swallowed a fatal error?

Did you actually read my previous postings? A component for playing
backgroundsound isn't important is it, but you use it the app. If it throws
an unexpected OutOfMemoryException because the soundfile you chose for
playing background sound and throws an unexpected OutOfMemoryException you
would close the application leaving the user no choice. Why? What kind of
Exception this component might throw - it does not affect - and should not
affect the rest of your application.

The next time the app will be started and the app would try to play the same
wavefile again it will crash again, so what now?
Instead you should have told the user that an unknwown problem occured
during load of the wavefile and let him choose another file. You should
never trust a 3rd party component that it throws only the specified
exceptions.

With your attitude, a not 100% correctly working plugin would always crash
(or shutdown if you like that more) the whole application. Why? There is
absolutely no reason for it.
Today, things are changing more and more rapidly and apps are larger and
complexer than ever - and one of the worst things you can do is relying on
every components of your app are working 100% correct.
The more paraniod you are, the better.
 
J

Joerg Jooss

David said:
That still does not strike me as a distinction that is always
meaningful; see below for more.

Um... it should be pretty obvious. You won't accidentally catch (swallow,
surpress) fatal errors.
Also, I prefer to not get into an
argument about JAVA and .net - frankly, I don't care what java does.

Ignorance is bliss?
If you wish to propose changing the .net model then please do so
without muddying the discussion with a comparison of .net versus java.

The inherent problem is that the FCL's exception hierarchy is screwed up
(Jeffrey Richter wrote about it back in '02). I'm not muddying the
discussion, I'm referring to a *simple* system that has worked astonglishly
well for quite a few people.
My perspective is that there is only a single exception that should
always be fatal - ExecutionEngineException - and that is because the
runtime itself has become corrupted; I regard this exception as a
form of CLR self-diagnostic exception.

All other exceptions could be handled by the application, including
StackOverflow, OutOfMemory, etc. The fact that today these are fatal
(the runtime shuts down) does not mean that they always should be
fatal.

Then we need new exception types. You cannot simply change the semantics of
an exception like that unless your code is meant *not* to be backward
compatible.

[...]
It would not be masked. The original exception is preserved as the
inner exception, and the same type could be rethrown if that was the
intended effect.

Maybe disguising is better a term than "masking", but the problem is that
even if you advise calling code to check inner exceptions explicitly, a
potentially fatal exception remains hidden initially. In my experience,
inner exceptions are rarely checked (just logged), but YMMV.
Also, the distinction between what is fatal and what
is recoverable is application-dependent.

Everything that makes the run-time bail out is fatal by default. That's the
"Error" category. These are the ones I'd like to see out of the mainstream
exception hierarchy.
I once tried to come up with a table of exceptions that were fatal
versus recoverable and add that to my exception handling, but after
testing it I gave up. The reason was simple - if the exception truly
is fatal the runtime will shutdown regardless of what your exception
handler does. Typically your handler will never even get called - the
runtime shuts itself down immediately. This behavior may change in
the future and if it does I will revisit this issue.

But there is the danger of delaying a severe problem to a later point in
time that makes an application failure much more unpleasant than an
immediate termination.

[...]
re: the manner of unit testing code - a layer that wraps-rethrows
exceptions - is to create a mock object and have a specific test
method in the mock object throw a specific exception that your own
code handles. The unit test invokes a method in your code that calls
into the mock object, not the actual third-party library. The mock
object throws the exception and your code is supposed to deal with
it. The unit test code then verifies that your code did the right
thing with it (whatever the "right thing" is supposed to do).

At no time was the actual 3rd party library invoked; the test will
not test the 3rd party library for new exception types that it might
throw. Therefore it cannot detect changes to the library.

It all depends on the test's implementation. You assume mocking. That's only
good for the facade's public API testing.
If your test requires your code to actually make calls into the 3rd
party lib then it is not a unit test, it is a system test. They are
not the same thing.

Sorry, but what notion of unit testing is that? Most code can't do anything
useful without calling into third party code.
In no case were fatal errors hidden or ignored - that is your own
interpretation, and one that is not always correct. It may be true
for your own application that any unhandled exception is fatal, but
that is not universal for all applications.

See above. Inner exceptions are well disguised, and you require the caller
to check explicity.

Cheers,
 
C

cody

I still don't see how ignoring or hiding potentially fatal errors
contributes to robustness.

I just had a look into the Rotor source. It seems that ms i using catch
(System.Exception) not to sparingly.
I found it in 1.307 files.
The funny things is, that mostly it was trivial stuff like this which made
even me wonder:

try
{
s = c.ToString();
b = Byte.Parse(s, NumberStyles.HexNumber);
}
catch (Exception)
{
String.Format(Environment.GetResourceString("Remoting_SOAPInteropxsdInvalid"
), "xsd:hexBinary", value);
}

But after revisiting the docs, I found that the Parse method can throw lots
of stuff:

ArgumentNullException
ArgumentException
FormatException.
OverflowException

Who would catch all that stuff everytime he parses a number? This shows us
again the broken exception model of .NET. Let me explain why:
Parse() is a static method and does not depend on a specific state on an
object or the system. Therefore the behaviour of this only method only
depends on it Arguments (Except due to an error in the .NET framework but
then your app would be in big trouble anyway).

I also have to wonder why FormatException does not derive from
ArgumentException?
The same problem with RankException and IndexOutOfRangeException with also
should derive from ArgumentException.

Iam also the opinion that int.Parse() should not throw OverflowException,
instead it should wrap that exception and throw something derived from
ArgumentException or ArgumentOutOfRangeException
 
J

Joerg Jooss

cody said:
Fatal exceptions like StackOverflow cannot actually caught. If you
catch them, they will rethrow automatically at the end of the catch
block.

Trick question: Is that a specified or an observed behaviour?
Did you actually read my previous postings? A component for playing
backgroundsound isn't important is it, but you use it the app. If it
throws an unexpected OutOfMemoryException because the soundfile you
chose for playing background sound and throws an unexpected
OutOfMemoryException you would close the application leaving the user
no choice. Why? What kind of Exception this component might throw -
it does not affect - and should not affect the rest of your
application.

You seem to live in a world of god applications with optional fancy stuff
that may break. Well, if the DAL of a 3-tiered web application bails out,
you better turn the whole thing off before users continue to type in data
that is destined to die in ether...
The next time the app will be started and the app would try to play
the same wavefile again it will crash again, so what now?
Instead you should have told the user that an unknwown problem occured
during load of the wavefile and let him choose another file. You
should never trust a 3rd party component that it throws only the
specified exceptions.

With your attitude, a not 100% correctly working plugin would always
crash (or shutdown if you like that more) the whole application. Why?
There is absolutely no reason for it.

You still don't get the notion of safely aborting, do you? If an app could
not load a third party component because of unknown exception, it could try
to disable it and restart with the component disabled. If the module is a
core component, the app must remain down, unless you like flogging a dead
horse.
Today, things are changing more and more rapidly and apps are larger
and complexer than ever - and one of the worst things you can do is
relying on every components of your app are working 100% correct.
The more paraniod you are, the better.

Hm... wasn't it me who wrote you cannot trust any code at all ;-)

Cheers,
 
D

David Levine

Um... it should be pretty obvious. You won't accidentally catch (swallow,
surpress) fatal errors.

Um...if the exception is fatal to the system you cannot swallow it;
otherwise it wouldn't be fatal. And
it should be pretty obvious for other exceptions, ones that are not fatal to
the system, what one application considers fatal might be non-fatal to
another.
Ignorance is bliss?

No, it is because those discussions usually wander into a statements of
religious belief, not engineering, and from there into immature name
calling. It should be possible to discuss issues in a neutral manner.
The inherent problem is that the FCL's exception hierarchy is screwed up
(Jeffrey Richter wrote about it back in '02).

Got a link? I've read just about everything he has written, and I do not
know which article you are referring to. I recall one complaint he had about
a misleading exception when invoking a method via reflection, and it turns
out he was wrong.
I'm not muddying the
discussion, I'm referring to a *simple* system that has worked astonglishly
well for quite a few people.

Simply asserting that a system works well does not prove it. Some systems
work well for small systems but do not scale at all to large systems, nor do
they necessarily evolve well.

There are many limitations in the exception handling implementation in the
current version of .net; attempting to distinguish between a fatal system
error versus all others is one that is way down the list of items of
importance.

see below. Basically, if your application can run (i.e. the runtime is not
comprised) then it is recoverable.
Then we need new exception types. You cannot simply change the semantics of
an exception like that unless your code is meant *not* to be backward
compatible.

You are conflating many separate issues; adding new exception types does not
solve the problem. Modifying the exception hierarchy will not solve the
problem either. If it is a fatal system error then you are so hosed there is
little the application can do - the runtime usually crashes shortly
thereafter. There would be no value would in adding a few new exception
types.

For all other exceptions, if the integrity of the system has not been
comprised then by definition the exception is not fatal. It may be that the
application may be corrupted, but that would be the fault of the
application, not the system, and one that I would consider to be a bug in
the application.

If you are concerned that an exception has corrupted the application, which
is certainly a valid concern, then there should be a means of detecting that
condition, reporting it, and acting on it. This is entirely application
specific. However, this is not a condition that the runtime will have
knowledge of.

Maybe disguising is better a term than "masking", but the problem is that
even if you advise calling code to check inner exceptions explicitly, a
potentially fatal exception remains hidden initially. In my experience,
inner exceptions are rarely checked (just logged), but YMMV.

Actually, I never advise that the inner exception should be checked - I
advise against it. However, it is possible to clone the exception type, wrap
the original and throw a new one of the same type. This allows the code to
add context information without changing the technical reason for the
exception. One can also rethrow the original exception, which is similar to
not catching it at all, but this also does not provide a means of adding
context information.
Everything that makes the run-time bail out is fatal by default. That's the
"Error" category. These are the ones I'd like to see out of the mainstream
exception hierarchy.

If the runtime bails out you are done anyway - it typically will not let you
do anything of importance, and it may not even allow the catch handler to
run. I see little value in adding more exceptions that explicitly mean that
the runtime is corrupted.
But there is the danger of delaying a severe problem to a later point in
time that makes an application failure much more unpleasant than an
immediate termination.

The runtime usually halts immediately so nothing will propagate to a later
time because there is no later time. Even if it did, if the runtime's
integrity has been compromised I would not want it to run anyway - it may do
more damage then not running will do. I would rather the runtime terminate
immediately then run the risk of corrupting additional data.

It all depends on the test's implementation. You assume mocking. That's only
good for the facade's public API testing.

That is one type of unit test, but not the only one - you can unit test any
method, not just public APIs. A unit test tests a code unit, not the the
external code that it uses.
Sorry, but what notion of unit testing is that? Most code can't do anything
useful without calling into third party code.

Again, that is a system test, not a unit test. At some level you may assume
that some libraries (e.g. BCL) are constant and are part of the unit, but I
certainly would not make that assumption with a 3rd party library,
especially one that may generate side-effects.

See above. Inner exceptions are well disguised, and you require the caller
to check explicity.
Not at all - you misinterpreted what I wrote.

Cheers,
 
J

Joerg Jooss

David said:
Um...if the exception is fatal to the system you cannot swallow it;
otherwise it wouldn't be fatal.

I'm thinking of cases where the runtime doesn't immediately go down and the
problem lingers for some time, e.g. because of the famous catch (Exception).
A simple test for example shows that OutOfMemoryExceptions is not fatal in
the sense that the CLR goes down. But once you run into it, you're in
trouble. The run-of-the-mill business application can do little but recycle.
No, it is because those discussions usually wander into a statements
of religious belief, not engineering, and from there into immature
name calling. It should be possible to discuss issues in a neutral
manner.

Yeah, but in the same spirit it should be possible to point out working
alternatives. I don't think anybody has acted like a zealot in the
discussion so far. But don't get me started on checked exceptions. Evil!
Evil! ;-) ;-)
Got a link? I've read just about everything he has written, and I do
not know which article you are referring to. I recall one complaint
he had about a misleading exception when invoking a method via
reflection, and it turns out he was wrong.

It's in his book .NET Framework Programming, and some of his comments are
reprinted in the .NET Framework Standard Library Annotated Reference (aka
SLAR).

Simply asserting that a system works well does not prove it. Some
systems work well for small systems but do not scale at all to large
systems, nor do they necessarily evolve well.

Sounds a bit academic to me. We're not talking about same fantasy technology
that nobody has ever used. Adding a distinct exception hierarchy for system
failures doesn't change anything fundamentally. Concerns regarding
scalability are a bit farfetched IMHO.
There are many limitations in the exception handling implementation
in the current version of .net; attempting to distinguish between a
fatal system error versus all others is one that is way down the list
of items of importance.

What's on the top of the list?
see below. Basically, if your application can run (i.e. the runtime
is not comprised) then it is recoverable.

Run maybe. Continue to do something meaninful? It depends.

You are conflating many separate issues; adding new exception types
does not solve the problem. Modifying the exception hierarchy will
not solve the problem either. If it is a fatal system error then you
are so hosed there is little the application can do - the runtime
usually crashes shortly thereafter. There would be no value would in
adding a few new exception types.

This is all based on the assumption that a fatal exception immediately
forces the system to go down. As long as this is not guaranteed or
specified, I'd rather see a simple mechanism in place that makes sure
developers don't produce potentially harmful code. And even if all this
wasn't required, the value of having a consistent exception type hierarchy
should be obvious.
For all other exceptions, if the integrity of the system has not been
comprised then by definition the exception is not fatal. It may be
that the application may be corrupted, but that would be the fault of
the application, not the system, and one that I would consider to be
a bug in the application.
If you are concerned that an exception has corrupted the application,
which is certainly a valid concern, then there should be a means of
detecting that condition, reporting it, and acting on it. This is
entirely application specific. However, this is not a condition that
the runtime will have knowledge of.

I totally agree. But right now, it means to catch (Exception) or install an
error handler with the unpleasant side effect that what I *may* catch a time
bomb, and I *may* handle it inappropriately.

[...]
If the runtime bails out you are done anyway - it typically will not
let you do anything of importance, and it may not even allow the
catch handler to run. I see little value in adding more exceptions
that explicitly mean that the runtime is corrupted.

It doesn't need to be new types -- all I want are types that are part of
distinct type family.

[...]
That is one type of unit test, but not the only one - you can unit
test any method, not just public APIs.

That's what I implied -- testing the internals of a wrapper is one example,
and mocking this would be plain wrong in this case.
A unit test tests a code unit,
not the the external code that it uses.

And if the whole purpose of a code unit is to wrap third party code?
Again, that is a system test, not a unit test. At some level you may
assume that some libraries (e.g. BCL) are constant and are part of
the unit, but I certainly would not make that assumption with a 3rd
party library, especially one that may generate side-effects.


There's of course a certain level of granularity where a code unit isn't a
unit anymore, but that's a fun story for another discussion.

BTW, a system test to me (i.e. in my company) is a test that exposes the
system to an end user. What you describe would be called an integration
test.

Cheers,
 

Ask a Question

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

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

Ask a Question

Top