Sruly
Sruly

Reputation: 10540

Should my custom Exceptions Inherit an exception that is similar to them or just inherit from Exception?

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?

Upvotes: 10

Views: 7148

Answers (10)

John Cuckaroo
John Cuckaroo

Reputation: 297

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 : SystemException
{
    /// <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)
    {
    }
}

Upvotes: 0

user117499
user117499

Reputation:

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.

Upvotes: 4

RA.
RA.

Reputation: 1423

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.

Upvotes: 0

Samuel Carrijo
Samuel Carrijo

Reputation: 17929

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...

Upvotes: 1

ATorras
ATorras

Reputation: 4303

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

Upvotes: 0

Aaron Daniels
Aaron Daniels

Reputation: 9664

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.

Upvotes: 1

Lucero
Lucero

Reputation: 60190

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.

Upvotes: 12

AllenG
AllenG

Reputation: 8190

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?");

Upvotes: 7

AnthonyWJones
AnthonyWJones

Reputation: 189457

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.

Upvotes: 2

BFree
BFree

Reputation: 103740

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?

Upvotes: 2

Related Questions