Without exceptions the possible control flow is entirely explicit. It would have at least been obvious that cleanup wasn't properly handled in the select function for all cases.
An exception was effectively injected from outside of the code via low level shenanigans. That's not "exceptions bad" that's "low level monkeying with program control flow can blow up in your face".
Of course, it's not uncommon to find unsafe Rust code that misbehaves badly when something panics, which is yet another of its hazards that I wish were better documented.
In this case, I'd put down the lesson as "exceptions in C++ are very dangerous if you're coming out of C code", since they can cause undocumented and unexpected behavior that ultimately led to the use-after-return issue here.
[0] https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#abort...
It can also result in logic errors if objects are used after their methods panic, but such usage is generally not expected to work in the first place.