[Moscow.pm] И все-таки, как правильно перехватить исключение?
Ivan Petrov
i.petro.77.00 на gmail.com
Сб Мар 23 13:14:00 PDT 2013
задача:
- перехватить исключение
подзадачи:
- передать исключение на более верхний уровень в измененном виде
- точно определить место где произошло исключение которое мы
перехватили
решение второй подзадачи приводит нас к двум вариантам.
вариант №1
~~~~~~~~~~
eval {
... код с исключением
};
if ($@) {
тут выпарсиваем место исключения из $@;
}
этот вариант очевидно ущербный в силу парсинга: в современных perl'ах,
а так же в всяких расширениях получается что не всегда можно точно
распарсить.
вариант №2
~~~~~~~~~~
local $SIG{__DIE__} = sub {
тут по значению, возвращенному функцией caller определяем место
исключения
...
die $_[0];
};
тут код выбрасывающий исключение
но второй вариант ущербен в связи с тем обстоятельством что невозможен
иерархический перехват.
то есть если код какого-либо модуля тоже хватает $SIG{__DIE__}, то мы
не можем определить место падения иначе как парся $@.
вот пример:
sub foo1 {
local $SIG{__DIE__} = sub {
print "die 1\n";
die $_[0];
};
die "привет 1";
}
sub foo2 {
local $SIG{__DIE__} = sub {
print "die 2\n";
die $_[0];
};
foo1;
}
foo2;
данная программа выводит строку 'die 1', а 'die 2', разумеется не
будет выведен никогда. если предположить что foo1 у нас в стороннем
модуле, то задача не решена.
есть еще какие-то мысли как перехватить исключение с точным
определением места исключения?
а общая задача банальная:
1. имеется некое большое приложение.
2. в этом приложении на самом верхнем уровне мы перехватываем
исключения и отправляем email о том что оно произошло
3. хотим дополнительно в письме отправить stacktrace, соответственно
код такой:
$SIG{__DIE__} = sub {
собираем stacktrce и определяем место где упало
die $_[0];
};
eval { main };
if ($@) {
отправляем email со stacktrace сохраненным в SIG{__DIE__}.
}
такой подход работает, все красиво, но есть куча внешних модулей (как
оказывается) которые так же ловят SIG{__DIE__}
у кого какие мысли?
Подробная информация о списке рассылки Moscow-pm