That is a poor example not a poor use case. I personally would pass in the parameters to a validation function and return a result that contained a pass or fail and a collection of failure messages to display to the user.
How I use exceptions is as follows.
Within functions. Let's say that you have a function that you are getting some data from the database and you are then constructing a structure from it. If the query returned has no values you have several options:-
You could return an empty structure and let the calling code deduce the problem from the fact the structure is empty. This is not ideal because then the application has to have complicated logic to address the missing data.
You could return a more complex datatype where one property is whether the process went ok and the actual data. Again this is not optimal as you have to then make this access the property on every call when the majority of the time you have data and again your application is dealing with this issue.
Or you could raise a custom exception with cfthrow indicating that there is no record that matches. This then means that you can choose to ignore the prospect of this error happening and let it bubble up to the onError handler or you could surround it in a try catch statement and deal with it there and then. This keeps your API clean and sensible.
Wrapping external errors let's say that you connect to an external API using cfhttp over https. Now this requires installing the certificate in your keystore otherwise it throws an error. If this certificate gets updated then it will start erroring again. In this instance I would wrap the call in a try catch and should this be the error I would wrap that in my own custom exception with a message detailing that we need to update the cert in the keystore so that any developer debugging it knows what to do to fix it without having to work it out. If it is not that particular error then I would cfrethrow it so that it bubbles up and is dealt with by whatever exception handling logic is above the call.
These are just a few examples, but there are more. To summarise I would say that throwing exceptions is a way of communicating up through the tiers of an application when something has occurred that is not the hoped for behaviour while keeping your API/Application logic clean and understandable.