tags:

views:

1146

answers:

10

I am creating some custom exceptions in my application.

If I have an exception that gets thrown after testing the state of an argument, Or I have an Exception that gets thrown after testing that an int is within the proper range, should my exceptions inherit ArgumentException and IndexOutOfRangeException or should they just inherit Exception?

+2  A: 

I'm just curious, why wouldn't you actually use the Exceptions that are already there? It sounds like these exceptions are exactly what you need, why are you against using those?

BFree
I am testing for things more specific than just an generic out of range. For example tesitng if an argument is in a state that allows persistance. In this case it is checking an argument but rally I want a more specific exception called ArgumentNotInPersitableState or something along thos lines
Sruly
For that particular case I would inherit Exception directly.
Matthew Scharley
Will your callers be catching your specific exception? If not, then you don't need your own exception type. Just use your own Message.
John Saunders
+2  A: 

Personally if I have an indexer and the index value is out of range then I would simply throw the existing IndexOutOfRangeException, I would not go to the trouble of inheriting from it.

If you are talking only about similar but not exactly the same exceptions, then take a look at the pattern provided in the framework. It doesn't look like this would make sense, inheritance describes an "is-a" relationship.

AnthonyWJones
Look at my comment to BFree. In that case the exception is an ArgumentException but it is a bit more specific.
Sruly
@Sruly: In that case my second paragraph holds, don't do it. Inherit from ApplicationException and be done with it.
AnthonyWJones
+6  A: 

Presuming that you really need a custom exception, I would inherit from the Exception most like what you're looking for, rather than just from Exception.

That said, I have found that, under most conditions, using correct wording in you Exception message will normally suffice over creating a whole new exception.

How, for instance is throw new IntOutOfProperRangeException(); significantly different from throw new ArgumentOutOfRangeException("The int value was too large?");

AllenG
+10  A: 

Since inheritance is used to specify which exceptions to catch, you should respect this primarily when taking a decision.

Think of an IOException which carries additional information, or a ArgumentException other than ArgumentOutOfRangeException or ArgumentNullException.

Lucero
+1  A: 

If you don't need to add any additional data to the exception, then I'd just use the native .NET exceptions like IndexOutOfRangeException.

However, if you needed to associate something with your exception that you can't natively do with IndexOutOfRangeException, then I'd inherit from it. The benefit here is that you can catch either your new custom exception type or IndexOutOfRangeException. Of course, if you catch the base type, you won't have your extra properties and such.

Aaron Daniels
Not easily anyway, you can still do a type check and cast... (eww)
Matthew Scharley
Yes, and I didn't mention it because I'd have to punch myself if I did.
Aaron Daniels
A: 

Hi,

Almost always I use the IllegalArgumentException (nulls and/or out-of-range values) and IllegalStateException for anything not more specific than IOException, SQLException, Null...

ATorras
+1  A: 

IMHO, there is no problem inheriting from another Exception. It makes even clearer the purpose of that exception. But make sure that everything that applies to the ParentException also applies to the ChildException you created. Otherwise, you could end up with the "Square extends Rectangle" problem...

Samuel Carrijo
Wouldn't a Rectangle extend a Square? Or is that the point? Havn't run into that phrase before...
Matthew Scharley
@Monoxide: no, Square extends (Is-A) Rectangle. As my "All squares are rectangles. Not all rectangles are squares"
AllenG
Point taken. Maybe it's that time of night again...
Matthew Scharley
just added a link to point out the "Square extends Rectangle" problem
Samuel Carrijo
A: 

If you just use the generic Exception you will never be able to trap specific exceptions that are custom to your application. If you just use

try 
{
}
catch (Exception ex)
{
}

You will catch every exception without being able to filter for specific errors.

Another reason I create a custom exception is to handle application specific exceptions that may occur for many reasons. This allows mean to throw an custom exception but customize the message associated with the exception. It also gives me another level of error handling that is for my specific application.

For example I have an enigineering application that sizes belt drive systems. The dll is also available for other people to use. I have an application exception that is thrown when an error occurs in the selection. The reason for the error can be for many reasons (invalid drive speed, incorrect horsepower requirements, etc.). Since there are many reasons for failure, a custom application exception allows me to give specific details for the failure.

This also allows me to document to users that method calls will throw application specific exceptions that they need to handle.

If your inheritting Exception class make sure to implement the constructors in the the base class that have a message, message + inner exception and serialized exception.

Here is an example I have.

/// <summary>
/// Drive error exception class. Thrown when a drive selection error has occured.
/// </summary>
[Serializable]
public class DriveException : ApplicationException
{
    /// <summary>
    /// Default constructor.
    /// </summary>
    public DriveException()
    {
    }
    /// <summary>
    /// Constructor used with a message.
    /// </summary>
    /// <param name="message">String message of exception.</param>
    public DriveException(string message)
        : base(message)
    {
    }
    /// <summary>
    /// Constructor used with a message and an inner exception.
    /// </summary>
    /// <param name="message">String message of exception.</param>
    /// <param name="inner">Reference to inner exception.</param>
    public DriveException(string message, Exception inner)
        : base(message, inner)
    {
    }
    /// <summary>
    /// Constructor used in serializing the data.
    /// </summary>
    /// <param name="info">Data stored to serialize/de-serialize</param>
    /// <param name="context">Defines the source/destinantion of the straeam.</param>
    public DriveException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }
}
John Cuckaroo
A: 

I think that it all depends on whether will you want to catch your ArgumentNotInPersitableState exception as an ArgumentOutOfRange. If there will be such a catch block (or if you're writing a framework, which will be presumable used by others) then yes you should inherit the relevant exception type.

RA
A: 

I think it's always safer to create a new Exception type. If you ever need to change how it is handled, it will be easier to find cases where you are or might be handling it. It's a lot easier to find MyException than to find the specific case of ArgumentOutOfRangeException. You seem to be able to provide some extra info in the exception, and it's not too much work to create an exception.

Also I tend to inherit a base application class like MyBaseException, and make sure to add a XML comments for the exception/s.

eschneider