which kind of Exceptions to throw?

C

cody

I have a method that gets called if the user presses a certain button.
If the object is in a state that doesn't allow the calling of that method,
what should I do? Should I better throw an InvalidOperationException or
should I derive my own exceptions from ApplicationException?

In general, it is not clear to me when to use the predefined exceptions and
when to create new ones by deriving from ApplicationException.

And a last question: what exactly is the difference between
NotImplementedException and NotSupportedException?
 
W

William Ryan eMVP

Hi Cody:

As far as the distinction between the two go, I believe the distinction is
generally considered to be that NotSupportedExcpetion is used in derived
classes where the functionality isn't built into the base class. I actually
wish MS used it more often b/c for instance, most every control in the CF
for instance has a 'Click' event and you can wire it in and it will compile,
it just won't work when you click on it b/c they didn't implement it. This
can lead to some logic problems.

As far as using Invalid or writing your own..it depends. How much info will
you need? If you have some internal data for instance that you want to know
about, you can include it in the excpetion's message (or some other
property) so you can get some customized information. For the most part,
I'd recommend using custom exceptions when you need finely grained
functionality or informationd. Another time is when your objects may need
some special functionality. For instance, if you had a LogIn class, you
might want to implement a special case scenario if someone tries to use a
protected login account (like 'sa' in SQL Server) or if they fail to
authenticate x number of times. You can trap this particularly to break out
of your routine and log it or whatever else.

By and large I think you could easily get by without ever deriving an
exception of your own and they are something you can definitely get carried
away with. But if you need specific info or have special cases where the
logic fit is clean, then implementing your own is legit.

HTH,

Bill
 
C

codymanix

By and large I think you could easily get by without ever deriving an
exception of your own and they are something you can definitely get carried
away with. But if you need specific info or have special cases where the
logic fit is clean, then implementing your own is legit.


The problem is, maybe today I develop a class which throws a
InvalidOperationException
if the User is trying to do something he can't do at the moment. Now later
after some time of development,
I recognize that I need to carry soem data in my exception.

So now what? I would break all client code when I use a derived exception
from ApplicationException now.
The code still compiles fine but if the exception is actually throw nobody
can catch it!

You can say what you want, but catching "Exception" instead of a specific
exception is always more secure as long as you take some action in the catch
clause and do not swallow it.
Nobody can tell me which kind of Exception a method can throw, even if the
docs tell you that this method will only throw FooException, the docs can be
outdated or incomplete. A programmer of a string format might be decided to
throw an ArgumentException instead of an IndexOutOfBoundsException if the
formatstring is to long. Or maybe later he recognizes it is better to throw
can FormatException instead.

I know catching a generic Excpeption is cosidered as sloppy coding, but if
Iam not 100% sure which exception to catch, I catch all. Especially with
InterOp you can never sure what happens,
in this case I additionally use a catch{} that will catch non-CLR exeptions
as well.
 
W

William Ryan eMVP

codymanix said:
The problem is, maybe today I develop a class which throws a
InvalidOperationException
if the User is trying to do something he can't do at the moment. Now later
after some time of development,
I recognize that I need to carry soem data in my exception.

So now what? I would break all client code when I use a derived exception
from ApplicationException now.
The code still compiles fine but if the exception is actually throw nobody
can catch it!


You're right. That's definitely a design consideration that should be
thought out b/c in your scenario, it coudl definitely cause some problems.
You can say what you want, but catching "Exception" instead of a specific
exception is always more secure as long as you take some action in the catch
clause and do not swallow it.
Nobody can tell me which kind of Exception a method can throw, even if the
docs tell you that this method will only throw FooException, the docs can be
outdated or incomplete. A programmer of a string format might be decided to
throw an ArgumentException instead of an IndexOutOfBoundsException if the
formatstring is to long. Or maybe later he recognizes it is better to throw
can FormatException instead.
Ok, but the exceptions will propogate up. If I have a sum method
public int sum(int a, int b){
return a+b;
}
I may want to catch an InvalidArgumentException for instance, but if I catch
System.Exception here, I'll catch OutOfMemoryExceptions and everything else
that could pop up unrelated to this problem.. So let's say one shows
up...it will just propogate up the chain to the caller. Would you really
want me dictating how your program is going ot handle such an excpetion?
That doesn' thave anything to do with my library per se, so why should I
handle it? Instead, I can just let it come back to you and you can do what
you want with it. If I catch it, unless I rethrow it it ends with me.
Depending on the situation (ie class library development), this could be
quite a problem.
I know catching a generic Excpeption is cosidered as sloppy coding, but if
Iam not 100% sure which exception to catch, I catch all. Especially with
InterOp you can never sure what happens,
in this case I additionally use a catch{} that will catch non-CLR exeptions
as well.

I don't think the point is to never use system exception, rather it's to
rarely use it and in targeted situations. It's there for a reason. But I
suspect one of the main reasons people advise against it is b/c if it's used
inappropriately it can introduce subtle (and perhaps not so subtle) logic
problems into your app.
 
C

cody

Ok, but the exceptions will propogate up. If I have a sum method
public int sum(int a, int b){
return a+b;
}
I may want to catch an InvalidArgumentException for instance, but if I catch
System.Exception here, I'll catch OutOfMemoryExceptions and everything else
that could pop up unrelated to this problem.. So let's say one shows
up...it will just propogate up the chain to the caller. Would you really
want me dictating how your program is going ot handle such an excpetion?
That doesn' thave anything to do with my library per se, so why should I
handle it? Instead, I can just let it come back to you and you can do what
you want with it. If I catch it, unless I rethrow it it ends with me.
Depending on the situation (ie class library development), this could be
quite a problem.

But the problem is that you never know for sure which exception is thrown.
A add method can throw an ArgumentException or an ArithmeticException who
knows.

The .NET exception hirarchy is somewhat stupid. I would take Exception like
OutOfMemory,
StackOverflow, InvalidProgram,NullReference and similar in another branch of
the hirarchy since nobody ever might want to throw them and they are really
rare circumstances when you want to catch them.

What will a wrog call to an Indexer throw? IndexOutOfRangeException or
ArgumentOutOfRangeException?
Again both are in a completely other branch or the exception hirarchy no you
have to catch either both or catch System.Exception.
I don't think the point is to never use system exception, rather it's to
rarely use it and in targeted situations. It's there for a reason. But I
suspect one of the main reasons people advise against it is b/c if it's used
inappropriately it can introduce subtle (and perhaps not so subtle) logic
problems into your app.

I know it is stupid to catch Exception but often is is really the most
secure way.

I suggest Microsoft should have designed there Exception hirarchy better.
This is how I would have it done:

SystemException
- StackOverflow
- InvalidProgram,
- NullReference
- OutOfMemory
- ArithmeticException
ApplicationException
-ArgumentException
-ArgumentNull
-ArgumentOutOfRange
-IndexOutOfBounds
-FormatException
-IOException
-InvalidOperationException

So in the branch SystemException are the exception you normally may not want
to catch,
and in ApplicationException are the ones that are commonly caught in
applications. So if I have
a method that throws InvalidOperationException and later I derive my own
exception from InvalidOperationException
clients stay compatible.
 
D

Dave

The .NET exception hirarchy is somewhat stupid. I would take Exception like
OutOfMemory,
StackOverflow, InvalidProgram,NullReference and similar in another branch of
the hirarchy since nobody ever might want to throw them and they are really
rare circumstances when you want to catch them.
I agree. It needs to be organized in a more hierarchal manner. The current
methodology is that because no one can figure out what a decent hierarchy
would look like they have fallen back on the position that the hierarchy
should be flat and wide (many types, few if any derived from any other).

At a minimum I would separate fatal from non-fatal exceptions. I would put
StackOverflow, OutOfMemory, and ExecutionEngine in that category. I think
the system will shutdown anyway whenever one of those occurs. I disagree
about some of the others you mention, but some sort of categorization would
be useful.

What will a wrog call to an Indexer throw? IndexOutOfRangeException or
ArgumentOutOfRangeException?
Again both are in a completely other branch or the exception hirarchy no you
have to catch either both or catch System.Exception.
but

I know it is stupid to catch Exception but often is is really the most
secure way.

I agree. I believe that in some cases it is entirely appropriate to do so.
However, this depends to a large extend on the software component - a
library should do little catching, and rarely should it catch everything.
However, a client GUI may need to catch everything so that the application
does not crash unexpectedly just because a bug in library control forgets to
catch a particular exception.

This is even more of a problem when a control that only catches a few
specific exceptions is part of a system that undergoes evolution. Some
component that the library uses may now throw a new exception that it was
not expecting, If the client did not have a backstop catch it may crash.
I suggest Microsoft should have designed there Exception hirarchy better.
This is how I would have it done:

SystemException
- StackOverflow
- InvalidProgram,
- NullReference
- OutOfMemory
- ArithmeticException
ApplicationException
-ArgumentException
-ArgumentNull
-ArgumentOutOfRange
-IndexOutOfBounds
-FormatException
-IOException
-InvalidOperationException

So in the branch SystemException are the exception you normally may not want
to catch,
and in ApplicationException are the ones that are commonly caught in
applications. So if I have
a method that throws InvalidOperationException and later I derive my own
exception from InvalidOperationException
clients stay compatible.

Perhaps one reason why they did not do so was because it would be difficult
to get agreement on this. I think it would be a boon if they had, and even
if we disagreed on some particulars, even a minimal standard is better then
the chaos we have now.

FYI, the current word from MSFT is to deprecate the use of
ApplicationException. Instead, you should derive your custom types directly
from System.Exception.
 
C

cody

At a minimum I would separate fatal from non-fatal exceptions. I would put
StackOverflow, OutOfMemory, and ExecutionEngine in that category. I think
the system will shutdown anyway whenever one of those occurs. I disagree
about some of the others you mention, but some sort of categorization would
be useful.

With which ones do you disagree?
I agree. I believe that in some cases it is entirely appropriate to do so.
However, this depends to a large extend on the software component - a
library should do little catching, and rarely should it catch everything.
However, a client GUI may need to catch everything so that the application
does not crash unexpectedly just because a bug in library control forgets to
catch a particular exception.

100% Agreed! Why let the whole Application crash only because one single
component does not behave exactly as it should.
That is a thing that I hate on Exceptions, they force you to take action all
the time in every corner of your application,
and if you forget one catch you cat get your whole application crashed by a
minor bug that affects nothing serious in the app
but throws an simple Exeption that is not caught.
Perhaps one reason why they did not do so was because it would be difficult
to get agreement on this. I think it would be a boon if they had, and even
if we disagreed on some particulars, even a minimal standard is better then
the chaos we have now.

Why would there be no agreement on this?
FYI, the current word from MSFT is to deprecate the use of
ApplicationException. Instead, you should derive your custom types directly
from System.Exception.

Actually? Interesting to hear. Where did you hear that?
 
D

Dave

cody said:
With which ones do you disagree?

e.g. I don't think that NullReference doesn't belong there.

I'd prefer it broken down into broad categories. For example,

AlwaysFatal
Others
etc.

would be useful. Why catch a StackOverflow or OutOfMemory if there's
nothing meaningful, including logging, that I can do at that point.
100% Agreed! Why let the whole Application crash only because one single
component does not behave exactly as it should.
That is a thing that I hate on Exceptions, they force you to take action all
the time in every corner of your application,
and if you forget one catch you cat get your whole application crashed by a
minor bug that affects nothing serious in the app
but throws an simple Exeption that is not caught.

Well, I actually disagree there. I believe that clients SHOULD have backstop
handlers on all threads. An uncaught exception actually means that some
piece of code somewhere has hit an unanticipated code path (a bug) and that
"something bad" may have happened. It may be fatal, it may not, and there
may not be any way for the code itself to know that If nothing else it
should allow the user to exit gracefully (if possible). Or ignore it and
pray.
difficult

Why would there be no agreement on this?

I think there would be lots of disagreements. Coming up with categories that
are specific enough to be useful and yet broad enough so that there are far
fewer categories then there are exceptions would be very challenging.
Actually? Interesting to hear. Where did you hear that?
At Brad Abrams blog.

http://blogs.msdn.com/brada/archive/2004/03/25/96251.aspx
 
C

cody

With which ones do you disagree?
e.g. I don't think that NullReference doesn't belong there.

Why would you ever catch a NullReferenceException? Ok, it is not as fatal as
OutOfMemory,
but it is a very unexpected exception and nobody would catch it, except if
you catch all to make sure
that a component does not throw unknown exceptions.

So I would make 3 Categories:

FatalException (unexpected, fatal, cannot recover, indicates serious bugs)
- StackOverflow
- InvalidProgram,
- OutOfMemory

SystemException (unexpected, nonfatal, indicates bugs)
- ArithmeticException
- NullReference
-ArgumentException
-ArgumentNull
-ArgumentOutOfRange
-IndexOutOfBounds
-FormatException

ApplicationException (expected, nonfatal, common, does not necessarily
indicate a bug, they can for example happen on wrong operations by the user)
-IOException
-InvalidOperationException
-SecurityException
-[All other exceptions that are based on hardware/OS failures, missing
hardware/OS-features, wrong versions, security issues, user decisions and so
on]

Alle three should be derived from System.Exception:

Exception
-FatalException
-ApplicationException
-SystemException

Now it is a really good Exception Hirarchy!

Indeed! That makes sense! I hope they will correct the docs/samples in
Future to be consistent with this new convention.
 

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