The arguments I give is for why Throw/Catch is a terrible control flow construct, a throw is an extremely dynamic goto that searches the call stack for its label, not guaranteed to be there by the way, and a catch is an extremely dynamic call that can resume control from any point underneath in the call stack. I don't know about you, but sounds to me like a disaster waiting to happen. Java tried to tame it by trying to incorporate exceptions into the type system, but it's half-baked and also comes with a big glaring hole called Unchecked Exceptions.
Errors or no errors, a bad control flow construct is a bad control flow construct. Error control flow deserve the same treatment as regular one.
>I find code that's full of ifs and multiple return statements and global error state variables to handle truly exceptional conditions
Two wrongs don't make a right. Ad-hoc error handling is awful, but so is Ad-hoc exception handling as well. There is plenty of error handling mechanism (either built-in to languages or as an architecture over boring code) that is not both.