You have to rely on good and up-to-date documentation or you have to dig into the source code to figure out what exceptions are possible. For a lot of third party dependencies (which constitute a huge part of modern software), both can be missing.
Error type is a mitigation, but you are free to e.g. panic in Rust if you think the error is unrecoverable.
A third option is to have effect types like Koka, so that all possible exceptions (or effects) can be checked at type level. A similar approach can be observed in practical (read: non-academic) languages like Zig. It remains to be seen whether this style can be adopted by the mainstream.
One problem with exceptions is composability.
You have to rely on good and up-to-date documentation or you have to dig into the source code to figure out what exceptions are possible. For a lot of third party dependencies (which constitute a huge part of modern software), both can be missing.
Error type is a mitigation, but you are free to e.g. panic in Rust if you think the error is unrecoverable.
A third option is to have effect types like Koka, so that all possible exceptions (or effects) can be checked at type level. A similar approach can be observed in practical (read: non-academic) languages like Zig. It remains to be seen whether this style can be adopted by the mainstream.