tags:

views:

58

answers:

4

Which exception should I use when the program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad.

For example:

int SomeFunction(int arg) {
    SomeEnum x = Whatever(arg, somePrivateMember);
    switch (x) {
        case SomeEnum.Value1:
            return SomeFunction1();
        case SomeEnum.Value1:
            return SomeFunction2();
        default:
            throw new WhatTypeToThrow();
    }
}

Clearly, ArgumentException is a long-shot here since the invalid value for x could have come from a bug in Whatever(), or an invalid combination of any arguments and/or the current instance state.

I'm looking for something such as an InvalidProgramStateException, InternalErrorException or similar.

Of course I could define my own, but I wonder if there is a suitable exception in the framework.

Edit: Removed the simple sample code to reduce amount of ArgumentException answers.

A: 

What about InvalidOperationException?

Martin Ingvar Kofoed Jensen
I sometimes use that one, but I think that exception says "You cannot do this", and what I want to say is "You should have been able to do this, but there is a bug".
erikkallen
+1  A: 

I think ArgumentOutOfRangeException is valid here and it's what I use. It's the argument to the switch statement that is not handled as it's out of the range of handled values. I tend to code it like this, where the message tells it like it is:

switch (test)
{
    case SomeEnum.Woo:
        break;
    case SomeEnum.Yay:
        break;
    default:
    {
        string msg = string.Format("Value '{0}' for enum '{1}' is not handled.", 
            test, test.GetType().Name);

        throw new ArgumentOutOfRangeException(msg);
    }
}

Obviously the message is to your own tastes, but the basics are in that one. Adding the value of the enum to the message is useful not only to give detail concerning what known enum member was not handled, but also when there is an invalid enum i.e. the old "(666)SomeEnum" issue.

Value 'OhNoes' for enum 'SomeEnum' is not handled.

vs

Value '666' for enum 'SomeEnum' is not handled.

chibacity
What if the switched value is not an argument?Btw, I removed the simple sample where the answer was likely to be ArgumentException.
erikkallen
@erikkallen The value is an argument to the switch statement as I stated in my answer.
chibacity
A: 

Here are suggestions that I've been given:

  • ArgumentException: something is wrong with the value

  • ArgumentNullException: the argument is null while this is not allowed

  • ArgumentOutOfRangeException: the argument has a value outside of the valid range

Alternatively, derive your own exception class from ArgumentException.

An input is invalid if it is not valid at any time. While an input is unexpected if it is not valid for the current state of the system (for which InvalidOperationException is a reasonable choice in some situations).

See similar question and answer that I was given.

Even Mien
The point of the question is that the invalid state is not related to the arguments. I agree, in the simple case, ArgumentException can do, but I don't think ArgumentException should be used as a generic "oops, didn't work, I bet it had to do with the arguments" exception.
erikkallen
The switch statement is what has the argument out of range.
Even Mien
A: 

"program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad."

In this case I would throw an ApplicationException, log what you can and exit the app. If things are that screwed up, you certainly shouldn't try to recover and/or continue.

automatic
I don't think this is a good idea. The original purpose of the ApplicationException (before it wes deprecated) was that any (expected) exception that your application throws should be derived from it.
erikkallen