Coder Perfect

In.NET, what exceptions should be thrown when parameters are erroneous or unexpected?

Problem

In.NET, what types of exceptions should be issued when parameters are erroneous or unexpected? When would I pick one over the other?

Which exception would you use if you passed in ’42’ to a function that expected an integer corresponding to a month? Even if it’s not a collection, would this be considered “out of range”?

Asked by Even Mien

Solution #1

ArgumentException, ArgumentNullException, and ArgumentOutOfRangeException are some of my favorites.

There are other possibilities as well, which don’t focus on the argument as much as they do on the call as a whole:

The key is to throw the exception that best conveys why the method can’t be invoked as it is. In an ideal world, the exception would explain what went wrong, why it went wrong, and how to repair it.

When error messages point to assistance, documentation, or other resources, I’m ecstatic. For example, Microsoft’s Knowledge Base articles, such as “Why do I get a “Operation aborted” error notice when I visit a Web page in Internet Explorer?” are an excellent start. They direct you to the KB article in the error message when you encounter the error. What they don’t do well is tell you why it failed in the first place.

Again, thanks to STW (ex-Yoooder) for his input.

I’d throw an ArgumentOutOfRangeException in response to your follow-up. Take a look at MSDN’s description of this exception:

So you’re passing a value in this example, but it’s not a legitimate value because your range is 1–12. The way you document it, on the other hand, makes it clear what your API throws. Because, although I may use the term ArgumentOutOfRangeException, another developer may use the term ArgumentException. Make it simple and keep track of what you’re doing.

Answered by JoshBerke

Solution #2

I voted for Josh’s answer, but there’s one more I’d like to add to the list:

System. InvalidOperation If the argument is legitimate, but the object is in a state where it shouldn’t be utilized, an exception should be thrown.

MSDN update:

Let’s imagine your object contains a PerformAction(enmSomeAction action) method with the enmSomeActions Open and Close as valid enmSomeActions. If you call PerformAction(enmSomeAction.Open) twice, the second call will throw an InvalidOperationException (since the arugment was valid, but not for the current state of the control)

Because you’re already doing the correct thing by programming defensively, I’ll only add one more exception: ObjectDisposedException. If your object implements IDisposable, you should always keep track of its disposed state in a class variable; if your object is disposed and a function is called on it, you should raise the ObjectDisposedException:

public void SomeMethod()
{
    If (m_Disposed) {
          throw new ObjectDisposedException("Object has been disposed")
     }
    // ... Normal execution code
}

To respond to your follow-up, it’s a thorny scenario, made even more so by the usage of a generic (not in the.NET Generics sense) data type to represent a specific set of data; an enum or other tightly typed object would be a better fit—but we don’t always have that control.

Personally, I’d go with the ArgumentOutOfRangeException and display a notice indicating that the valid values are 1 to 12. My explanation is that when you talk about months, you expect a value in the range of 1-12, assuming that all integer representations of months are accurate. If just specific months were valid (for example, months with 31 days), you wouldn’t be dealing with a Range per se, and I’d issue a generic ArgumentException with the valid numbers listed, as well as documenting them in the method’s comments.

Answered by STW

Solution #3

Depending on the actual amount and the most appropriate exception:

Simply derive your own exception class from ArgumentException if this isn’t accurate enough.

Yoooder’s response educated me. An input is invalid if it is not legitimate at any point in time, while an unexpected input is one that is not valid for the current state of the system. As a result, in the latter instance, an InvalidOperationException is a good option.

Answered by Daniel Brückner

Solution #4

argument exception.

Answered by Syed Tayyab Ali

Solution #5

ArgumentException:

Specific types of invalidity have their own subclasses. There are summaries of the subtypes and when they should be used in the link.

Answered by Ben S

Post is based on https://stackoverflow.com/questions/774104/what-exceptions-should-be-thrown-for-invalid-or-unexpected-parameters-in-net