Question

When should I use InvalidArgumentException and when UnexpectedValueException? They look the same to me.

Note that one extends LogicException and the other one extends RuntimeException, so the difference shouldn't be so subtle IMO.

Was it helpful?

Solution

Looking closely at the descriptions on the manual pages:

InvalidArgumentException

Exception thrown if an argument is not of the expected type.

(The description was Exception thrown if an argument does not match with the expected value. until mid-2014, but was changed when PHP 5.6 got introduced)

UnexpectedValueException

Exception thrown if a value does not match with a set of values. Typically this happens when a function calls another function and expects the return value to be of a certain type or value[,] not including arithmetic or buffer related errors.

From this, we can conclude that InvalidArgumentException is intended to check types of arguments passed to a function, while UnexpectedValueException is intended to verify values vs valid value sets, possibly during the internal computations of a function (e.g. values returned from other functions).

Note that checking the values of arguments is kind of gray area here; arguably, since InvalidArgumentException extends LogicException, it should only handle situations which should lead directly to a fix in your code. Since throwing an exception in case of out-of-range input values can be a completely expected runtime behaviour, this leaves UnexpectedValueException (which extends RuntimeException) as the only candidate in such cases.

OTHER TIPS

I guess the largest difference is "argument" vs "value".

The way I see it is that InvalidArgumentException is for (passed) arguments, whereas UnexpectedValueException applies to (returned) values. Also there's a subtle but important difference between "invalid" and "unexpected" - which also explains why the first is LogicException and the second a RuntimeException.

For example: say i've got a function that utilizes the Twitter-api called: getLastMessageDate($userid): You pass a (numeric) user-id and it returns the date of the last message of that user as yyyy-mm-dd string.

Now, suppose I call this function with a string as argument instead of a number. At this point I can call an InvalidArgumentException, because the provided argument is invalid for this function. These checks can be done by logic - because a variable is either numeric or it is not. Therefore it's a LogicException.

However, the return value of a function may not be verifiable by logic - especially when you're dealing with (third-party) dynamic content. Because you can never know exactly what your function is going to return. (if you would, this would arguably render your function useless.)

So, this time I call my function with a (valid) user-id and my function gets the date of the last message of that user. With this date I would like to do something, like some formatting.

Now imagine the guys at Twitter did something wrong and instead of my expected yyyy-mm-dd date-string, I get an empty string or a different string saying 'blaaaa'. At this point, i can throw an UnexpectedValueException.

I can't say that this value is "Invalid" - I asked for a string and I got a string. But it is however not the "kind of string" i was expecting: therefore Unexpected ValueException.

Hope this clears something up. This is my first post - so far I've learned that writing down what's in my head isn't the easiest thing (also English is not my native language).

My understanding is that InvalidArgumentException, being a LogicException, should be used if you check an argument against a fixed list of possible value ranges. For example, checking if user entered data contains only numbers. The program logic can be expected to handle these value ranges.

UnexpectedValueException, being a RuntimeException (errors that can only be found on runtime / cannot be detected at compile time), would be used for Exceptions that occur outside of foreseeable and specified input ranges (possibly as a last resort after the "logic" checks above).

The key to answering this question might be the Unexpected... in UnexpectedValueException. Unexpected means there is no handling for this value in the program logic. Invalid, on the other hand, suggests that this value has been handled.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top