Also, exception systems usually come with built in stack trace support, "this error caused by this other error" support, debugger integration ("break the first time something goes wrong"), and tons of other useful features.
(Common Lisp conditions are even better, but you can't have everything.)
You can't just wave the word "goto" around as if it were self-evident that nonlocal flow control is bad. It isn't.
> And nearly always, after an exception is “handled”, the application is actually in an unknown state and cannot be reasoned about.
That's not been my experience at all. Writing exception safe code is a matter of using your language's TWR/disposable/RAII/etc. facility. A programmer who can't get this right is going to bungle explicit error handling too.
Oh, and sum types? Have you read any real world Rust code? Junior developers just add unwrap() until things compile. The result is not only syntactic clutter, but also a program that just panics, which is throwing an exception, the first time something goes wrong.
Many junior developers struggle with error handling in general. They'll ignore error codes. They'll unwrap sum types. They might... well, they'll propagate exceptions non-fat ally, because that's the syntactic default, and that's usually the right thing. We have to design languages with misuse in mind.