Is it semantically sound? As far as I understand, you have this (in pseudo-code):
try { user_code();
There are two possibilities:
user_code() and clean_up() will never run the same run, in which case you can simply write it as sequential code without any funny guard business, and it will work.user_code() and clean_up() may at some point abandon the same run.
If both functions can throw, you have two active exceptions. I do not know a single language that can handle several currently active exceptions, and I am sure there is a good reason for this. Perl adds (in cleanup) and makes an exception impossible; C ++ calls terminate() , Java automatically disables the original exception , etc.
If you just exited eval in which both user_code() and cleanup() user_code() exceptions, what do you expect to find in $@ ?
This usually means that you need to handle the cleanup exception locally, possibly ignoring the cleanup exception:
try { user_code(); } finally { try { clean_up(); } catch {
or you need to choose an exception to ignore when both throw (which the DVK solution does, ignore the user_code () exception):
try { user_code(); } catch { $user_except = $@ ; } try { cleanup(); } catch { $cleanup_except = $@ ; } die $cleanup_except if $cleanup_except;
or in any way combine the two exceptions into one exception object:
try { user_code(); } catch { try { clean_up(); } catch { throw CompositeException;
I believe that there should be a way to avoid repeating the clean_up() in the above example, but I can't think about it.
In short, not knowing what, in your opinion, should happen when both parts are thrown, your problem cannot be solved.
Philip potter
source share