Best Practices Class Exceptions

S

SStory

When I right a class, I am wondering what are the best practices for error
handling?

Do I try..catch and trap the error and if so what do I do with it? Because
most likely the class user will want to know the information in the
exception....
That being the case do I just not catch it and let the user of the class
catch it and get all the information?

I know I could catch it and throw my own, but I'd have to tell them the same
thing the original exception already has so I think what is the point?

Please give me some best practices advice on this.

thanks,

Shane
 
H

Herfried K. Wagner [MVP]

* "SStory said:
Do I try..catch and trap the error and if so what do I do with it? Because
most likely the class user will want to know the information in the
exception....
That being the case do I just not catch it and let the user of the class
catch it and get all the information?

I know I could catch it and throw my own, but I'd have to tell them the same
thing the original exception already has so I think what is the point?

Take a look at the constructor of 'Exception'. You can specify an
'InnerException' there. Catch the exception and create a new exception
object and specify the caught exception as inner exception.
 
D

David Browne

SStory said:
When I right a class, I am wondering what are the best practices for error
handling?

Do I try..catch and trap the error and if so what do I do with it? Because
most likely the class user will want to know the information in the
exception....
That being the case do I just not catch it and let the user of the class
catch it and get all the information?

I know I could catch it and throw my own, but I'd have to tell them the same
thing the original exception already has so I think what is the point?

Please give me some best practices advice on this.

If you're really writing a class library, the rules are a little more
strict. For a library designer you should validate all of your input
arguments and immediately throw an ArgumentException or
ArgumentNullException or ArgumentOutOfRangeException on invalid input. This
will prevent you throwing confusing exceptions later, like an unhelpful
NullReferenceException or IndexOutOfRangeException.

If your type is stateful, and your methods can only be called when the
object is in a certian state then you should check that and throw an
InvalidOperationException if the object is in the incorrect state (eg not
"open", or "conneced" or "initialized").

In addition you should document if a particular kind of exception is
especially likely to be thrown.

But these are really all examples of a general proposition. The exceptions
thrown by a class library should clearly indicate what really went wrong.
You shold never throw an InvalidCastException or a NullReferenceException,
but you shouldn't really catch them either. Rather you should structure
your code and validate your inputs so that these exceptions don't get thrown
in the first place.

You should catch and rethrow exceptions when either the type of the
exception is misleading, or you need to bundle information from that stack
level to make the exception meaningful. I find custom exceptions only
really usefull for bundling common state information into a thrown
exception. So if you find yourself concatenating the same kinds of
information into a thrown exception's error message, condisder adding your
own Exception subtype with instance fields to hold this information.

David
 
S

SStory

Yes but the question is do I want to?
What do I gain by that?
Suppose I write a class

and then I use that class

when I call method X, wouldn't I just want to try catch around that call and
not have the method trap the error, since the one needing to handing it
would be the calling app?

I am confused about this, and not sure what the best practice is.

Thanks,

Shane
 
S

SStory

Thanks for the thoughts.


David Browne said:
If you're really writing a class library, the rules are a little more
strict. For a library designer you should validate all of your input
arguments and immediately throw an ArgumentException or
ArgumentNullException or ArgumentOutOfRangeException on invalid input. This
will prevent you throwing confusing exceptions later, like an unhelpful
NullReferenceException or IndexOutOfRangeException.

If your type is stateful, and your methods can only be called when the
object is in a certian state then you should check that and throw an
InvalidOperationException if the object is in the incorrect state (eg not
"open", or "conneced" or "initialized").

In addition you should document if a particular kind of exception is
especially likely to be thrown.

But these are really all examples of a general proposition. The exceptions
thrown by a class library should clearly indicate what really went wrong.
You shold never throw an InvalidCastException or a NullReferenceException,
but you shouldn't really catch them either. Rather you should structure
your code and validate your inputs so that these exceptions don't get thrown
in the first place.

You should catch and rethrow exceptions when either the type of the
exception is misleading, or you need to bundle information from that stack
level to make the exception meaningful. I find custom exceptions only
really usefull for bundling common state information into a thrown
exception. So if you find yourself concatenating the same kinds of
information into a thrown exception's error message, condisder adding your
own Exception subtype with instance fields to hold this information.

David
 
J

Jay B. Harlow [MVP - Outlook]

Shane,
Do I try..catch and trap the error and if so what do I do with it?
IMHO that is the big question: "what do I do with it", if you do not have a
specific answer to that question, IMHO you should NOT be catching the
exception.

Ergo I find it better to not catch exceptions, rather I simply let them
float up to the Global Exception Handlers. That is not to say that I don't
use Try/Catch, I use Try/Catch where I have something specific to do with
that specific exception.

In other words Try/Finally is good, Try/Catch not so good.

See the MSDN Mag article below for details.

I normally use a global exception handler for logging and display to the
user. I use try/finally more then I use try/catch. I only use try/catch when
there is something specific that I need to do with the exception, otherwise
I let my global exception handlers handle the exception.

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/issues/04/06/NET/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.

Note David has some excellent comments on argument validation to your class
libraries. Especially if those class libraries are going to be used outside
of your current solution.

Hope this helps
Jay
 
S

SStory

Yes it does help.
Thanks Jay, for all the good information. I am of the same thought....if I
don't need to do anything with it, let it float up and be dealt with by the
caller. Unless it is a public class library.

Shane
 
J

J. Alan Rueckgauer

In addition to the other recommendations, when I'm writing classes that
could be invoked in a stateless environment, or where throwing an exception
could cause confusion with some types of other components (generally COM and
ASP classes, but frequently in ASPX pages), I use boolean methods and
maintain some properties to hold the last error details. This works quite
nicely by itself or in concert with local SEH. If a method returns false,
the caller knows something went wrong underneath it. If it still has a
reference to the object, it can interrogate the error detail property(ies)
and decide whether to act on it or send it back up the chain; at least it
knows whatever was being done failed.

Alan
 

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