An exceptional condition is arguably anything that means some call in your program can't do its job.
Passing error conditions up the call stack to the control layer that displays and/or logs a relevant message is a pain.
Exceptions make it less painful.
Catch blocks should be used sparingly, sure. If you're using them close to where the error is thrown then maybe you should consider an error code-oriented approach. But catch blocks in controller code (or better yet, meta-controller code)? Sure.
Passing error conditions up the call stack to the control layer that displays and/or logs a relevant message is a pain.
Exceptions make it less painful.
Catch blocks should be used sparingly, sure. If you're using them close to where the error is thrown then maybe you should consider an error code-oriented approach. But catch blocks in controller code (or better yet, meta-controller code)? Sure.