The agent finds functions returning numeric or string codes for failure; verifying error handling requires the agent to trace every caller and check whether the code is inspected.
Failures throw exceptions the agent reasons about as separate control flow; the type system marks the failure path.
Before the refactoring
function withdraw(amount) {if (amount > balance) return -1;balance -= amount;return 0;}
After the refactoring
function withdraw(amount) {if (amount > balance) throw new InsufficientFunds();balance -= amount;}
Every caller is a chance to silently swallow the error; the agent verifying correctness must audit every call site for the check.
Exceptions for predictable conditions misuse the mechanism; the agent ships try/catch around expected outcomes that should be values.
The agent reasons about success and failure paths separately; cleanup happens via finally / try-with; forgetting to handle no longer silently swallows.
Throwing for predictable conditions (not-found, validation failure) makes expected outcomes look like bugs to the agent reading the catch blocks.