@amoroso @nedbat Exceptions are three GOTOs in a trenchcoat. :)
Seriously though, it wasn't until reading Object Oriented Software Construction by Bertrand Meyer that I became comfortable with exceptions. This the book that introduces the Eiffel language and Design by Contract (DbC). It's a great book - clear and insightful, engaging and readable for a textbook - very highly recommended.
Meyer's position was that you clearly define the scope of responsibility of a routine as well as its requirements and expectations. Exceptions are for exceptional conditions _only_ - issues where the routine's contract with its caller is broken. DbC makes you think more clearly and intentionally when you create a routine; part of that is clearly documenting which exceptions a routine can throw. One of my biggest complaints about OO systems is that there's no way to get a complete list of exceptions that could be emitted from a function call so you can effectively handle them; I'm not sure that's even possible. Either way it makes the code difficult to reason about. Not that status codes are any better in practice - the tradeoff seems to be between clear implementation code and routines with clearly documented behavior.
As noted in the post, some languages don't have exceptions; here's an exploration into error handling in Modern Fortran that tries to do better than just returning an integer https://matthiasnoback.nl/2025/07/fortran-errors-and-error-handling-part-1-exploration/