100% depends on what you want to achieve.
If a path is invalid and you want to inform it to the user, you can choose between returning a success value or throwing an exception by what's more suitable for your code architecture.
In other cases, where something can go wrong without the user being responsible for it, or needing to be informed, you usually let exceptions get thrown and handle them in catch
blocks in the appropriate places.
The thing to remember is that you can always perform an if
check and throw an exception of your own in case of invalid state, rather than letting the invalid state cause an exception by itself. The main difference there is in the data thrown with the exception (stack trace, message, etc), but can also be expressed in performance (you wouldn't want to try a high-cost operation if you can first perform a low-cost check to make sure it will succeed). Try-catch blocks add a BIT of an overhead as well, but I wouldn't consider that to be significant.
The questions to ask are:
- Does invalid state causes the whole operation from above to fail?
- Where and how does the code handle invalid state?
- Does the code "fix" the invalid state and tries again?
- Is the invalid state originating from a user error or a code issue?
- How costly the operation is, in contrast to how costly the validation check is?
Edit: Check out Yuval's link in the comment to get better understanding of the costs of try-catch blocks.
The validation check is almost always very low-cost, so in conclusion I would say: Perform the check, even if you intend to throw your own exception in case of invalid state.