The worst thing about exceptions is that you can't tell from the type signature of a function whether it might throw one. So you have to hope it's documented, guess at whether try-catch is necessary, or reading through the entire call stack.
I personally much prefer Rust style Result which also can't be ignored, and puts fallibili5y in the function signature.
> The worst thing about exceptions is that you can't tell from the type signature of a function whether it might throw one.
In Java exceptions can be part of a method's declared type information, so handling is checked at compile time and IDEs can display the info.
Unfortunately certain Java missteps made this design unpopular these days. For example, for many years new String(bytes, "UTF-8"); made it mandatory to catch a UnsupportedEncodingException despite the language spec guaranteeing UTF-8 would be available. A later version of Java addressed it, but still...
Java's problem with checked exceptions is that they didn't add them fully to the type system (the lambda problem), and they never added any syntax sugar to make them easier to deal with. I really love checked exceptions and wish we could get some improvements.
Or you can assume exceptions can be thrown and capture and log coming from a base class in a centralized place (and probably refine incrementally what to do with each group without dirtying all the logic inside the functions themselves).
For Rust result in C++ you have optional and expected. But they have their own problems, like rewriting function signatures all the way up the stack if you notice an error was possible when adding code.
But it enables incremental addition of errors and you can decide later what to do exactly, so I still tend to see it as an advantage.
It is like defer the error handling and centralize later.
If you want to handle an error in place immediately, prpbably it is not an exception what you want.
But if you need it is a fatal error, I do not see any harm, since the most you will do with that exception is to unwind and log or telemetry or whatever to tracke the errors.
I personally much prefer Rust style Result which also can't be ignored, and puts fallibili5y in the function signature.