Should I throw in current method or let the later method throw it

74 views Asked by At

I am having a hard time when it comes to good design.
I am unsure if I should let a later method throw an exception or if I should throw it myself.
Thing is:

The type of the Exception changes based on the method being called. In the later method it might be an InvalidOperation but in the current method an ArgumentException may better fit.

Now should I really perform all the checks in order to throw the correct type of exception or should I let the deeper method throw the incorrect type of exception?

Consider this:

private bool _canWaste = false;



/// <summary>
///    Runs around and wastes something.
/// </summary>
/// <exception cref="InvalidOperationException">
///     Thrown when <paramref name="CanPower"/> is false.
/// </exception>
public void Run(bool CanWaste) {
   _canWaste = CanWaste;
   // <- Should I check if we can waste and throw an ArgumentException here or 
   //    throw the 'wrong' type later in Waste?
   Waste();
}



/// <summary>
///    Wastes something.
/// </summary>
/// <exception cref="InvalidOperationException">
///     Thrown when we cannot waste.
/// </exception>
private void Waste() {
   if(!_canWaste) throw new InvalidOperationException("We cannot waste.");
   /* ... */
}

This is a simple example (that does not make sense) where it would be easly done.
But of course, there are methods where the evaluation is much harder.

Another option would be to catch the exception and throw a new of the correct type.
But I guess that would hit performance and register some uncool stuff in the ouput.

2

There are 2 answers

4
Habib On BEST ANSWER

Do not throw or let the code throw incorrect type exception, that doesn't help any one. If you get an invalid argument throw InvalidArgumentException, otherwise let the exception bubble up to the caller from the library.

From the description, it sounds like that you are trying to control the execution flow through exceptions. Do not do that. Exceptions are "Exceptions", use them when there are exceptional scenarios that you can't avoid.

There is no point in catching and re-throwing that exception, unless you want to reset the stack trace yourself.

3
Tim Schmelter On

In general you should always throw as fast as possible. On that way you prevent that code is executed in an invalid state which could cause major issues(f.e. you delete all records instead of one because the filter was incorrect).

Also, if you throw quickly you ensure that the caller gets the most meaningful message.

public void Run(bool CanWaste)
{
    if(!CanWaste)
        throw new ArgumentException("CanWaste must be true", "CanWaste");
    Waste();
    // ...
}

However, if you don't know if the argument is invalid and the determination is expensive(f.e. you need to execute it) then let the deeper method throw. You could handle the InvalidOperationException in the calling method:

public void Run(bool CanWaste)
{
    _canWaste = CanWaste;

    try
    {
        Waste();
    }catch(InvalidOperationException ioe)
    {
        throw new ArgumentException("CanWaste must be true", "CanWaste", ioe);
    }
}

Of course in this case it's easy to determine if the argument is valid. It's also not the best example since a bool paramater that can only be true doesn't make much sense.