Rust has unwinding, which indeed opens a whole can of worms, but to say that it has exceptions is to miss the point. Rust has nothing anywhere near close to first-class resumable exceptions as surfaced in, say, Java. Not only is the `catch_unwind` function (it's not called `catch_panic`, btw) deliberately difficult to use (specifically to deter people from using it as a general error handling mechanism), the language deliberately defines an alternate compilation mode where unwinding does not exist and hence any attempt to "catch" it will fail. As a result, I have never once seen Rust code APIs that use `catch_unwind` as a mechanism for error handling; the purpose of that function is to prevent unwinding from crossing FFI boundaries.
Technically speaking, Rust does have exceptions with its unwinding feature. The panic! macro throws an exception, and catch_panic allows you to catch it. It is implemented exactly the same way as C++ exceptions, with the accompanying code bloat and performance pessimization, and you have to think about exception safety exactly the same way when writing unsafe code.