When to throw IllegalStateException vs IllegalArgumentException?

Abhijit Sarkar picture Abhijit Sarkar · Feb 11, 2018 · Viewed 9.9k times · Source

Let's start with the Javadocs:

IllegalStateException

Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.

IllegalArgumentException

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

The problem with the above is that they are very black and white. Consider a use case where a method is parsing a file provided by the caller. The file exists, is readable, and is in the correct format. However, some content in the file is non-compliant with the business rules. What would be an appropriate exception to throw in this case - IllegalStateException or IllegalArgumentException?

Looking at various libraries that provide assertions, like Guava Preconditions or Spring Assert, it appears that there is no consensus. There are some good discussions here and here, but none provide a conclusive answer to the common use case I stated above.

Disclaimer: I understand that I didn't show some code, but I believe this is a specific and pragmatic question to consider for good API design. Let's pretend for a moment that we're back in the good ol' days of stackoverflow, when people were happy to discuss pragmatic questions rather than downvoting anything that doesn't look like homework.

Answer

Saclyr Barlonium picture Saclyr Barlonium · Feb 11, 2018

Putting in other words:

The IllegalArgumentException is thrown in cases where the type is accepted but not the value, like expecting positive numbers and you give negative numbers.

The IllegalStateException is thrown when a method is called when it shouldn't, like calling a method from a dead thread.

I don't see how they could mix. In your question about the file with problems, I think that throwing either a ParseException or an IOException would be more appropriate.