Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There's no reason that throwing exceptions in finalisers must be prohibited. It's just bad design.

Modern Java provides the concept of suppressed exceptions. Basically an exception can maintain the list of suppressed exceptions.

When stack unwinds, just allow finaliser to throw an exception. If it threw an exception, either propagate it to the handler, unwinding stack as necessary, or add it to the current exception as a suppressed exception. Exception handler can inspect the suppressed exceptions, if necessary. Exception print routine will print all suppressed exceptions for log visibility.

Java does not do it properly for finally blocks, instead overwriting current exception, probably because the concept of suppressed exception was introduced in the later versions and they wanted to keep the compatibility.

But it can be done properly.



IIRC C++ and Rust don't technically prohibit throwing exceptions out of destructors; it's triggering unwinding during unwinding that's the main problem.

Does make me wonder about the specifics behind that. I had assumed that there are some kind of soundness issues that force that particular approach (e.g., https://github.com/rust-lang/rust/pull/110975, "Any panics while the panic hook is executing will force an immediate abort. This is necessary to avoid potential deadlocks like rustc hangs after ICEing due to memory limit #110771 where a panic happens while holding the backtrace lock."; alternatively, some other kind of soundness issue?), but I don't have the knowledge to say whether this is a fundamental limitation or "just" an implementation quirk that basically got standardized. Rust' first public release was after Java 7, so in principle the precedent was there, for what it's worth.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: