Это семантически звучит?Из того, что я понимаю, у вас есть это (в псевдокоде):
try {
user_code(); # might throw
}
finally {
clean_up(); # might throw
}
Есть две возможности:
user_code()
и clean_up()
никогда не будет выбрасывать в одном запуске, в этом случае вы можете просто написать его как последовательный код без каких-либо забавных мер охраны, и он будет работать. user_code()
и clean_up()
могут в какой-то момент оба выполнить один и тот же прогон.
Если обе функции могут выдавать, у вас есть два активных исключения.Я не знаю какого-либо языка, который может обрабатывать несколько активных в настоящее время генерируемых исключений, и я уверен, что для этого есть веская причина.Perl добавляет (in cleanup)
и делает исключение недоступным; C ++ звонки terminate()
, Java отбрасывает исходное исключение без предупреждения и т. Д. И т. Д.
Если вы только что вышли из eval
, в котором оба user_code()
и cleanup()
выдали исключения, что вы ожидаете найти в $@
?
Обычно это означает, что вам нужно обрабатывать исключение очистки локально, возможно, игнорируя исключение очистки:
try {
user_code();
}
finally {
try {
clean_up();
}
catch {
# handle exception locally, cannot propagate further
}
}
или вам нужно выбрать исключение, которое будет игнорироваться, когда оба throw (что и делает решение DVK; оно игнорирует исключение user_code ()):
try {
user_code();
}
catch {
$user_except = $@;
}
try {
cleanup();
}
catch {
$cleanup_except = $@;
}
die $cleanup_except if $cleanup_except; # if both threw, this takes precedence
die $user_except if $user_except;
или как-то объединить два исключения в одно исключениеобъект:
try {
user_code();
}
catch {
try {
clean_up();
}
catch {
throw CompositeException; # combines user_code() and clean_up() exceptions
}
throw; # rethrow user_code() exception
}
clean_up();
Я чувствую, что должен быть способ избежать повторения строки clean_up()
в приведенном выше примере, но я не могу думать об этом.
Короче говоря, беззная, что, по вашему мнению, должно произойти, когда обе части бросают, ваша проблема не может быть решена.