When a method may throw for more than one reason, the thoughtful programmer might ask “which exception should be thrown?”
Consider a method which performs argument validation, is cancelable, and also might throw based on the state of the object. What order should these validations occur so that the best exception is thrown? Here is my own answer to that question, as an in-order list of verifications that prioritize the exception types and reasons:
- ArgumentException – always validate arguments first (assuming it’s a cheap operation). Regardless of the cancellation token or the state of the object, if the caller ever passes in invalid inputs, it’s a bug in their code and you don’t want to miss an opportunity to throw to help them notice their bug.
- OperationCanceledException – It’s quite acceptable that the caller knows your object is in an invalid state (disposed, corrupted, etc.) and with the transition to that state they canceled the token that came into your method. So throwing OperationCanceledException is better than throwing some other exception about the invalid state of your object because they presumably already know about that.
- ObjectDisposedException – at this point, if the object is already disposed, it’s time to let them know using the best exception for it.
- InvalidOperationException – if your object is in any other state that isn’t prepared for this call, throw this with a helpful exception message describing why it’s inappropriate.