[Moscow.pm] И все-таки, как правильно перехватить исключение?

Andrei andrei.protasovitski на gmail.com
Сб Мар 23 15:42:36 PDT 2013


Вариант 1 ещё и неверный.

eval {
    # code
    1; # return true
} or do {
    my $error = $@ || "Zombie error";
    # parse $error
}

Существуют ещё всякие TryCatch, Try::Tiny и т.п.


23 марта 2013 г., 21:14 пользователь Ivan Petrov
<i.petro.77.00 на gmail.com>написал:

> задача:
>
> - перехватить исключение
>
> подзадачи:
>
>  - передать исключение на более верхний уровень в измененном виде
>  - точно определить место где произошло исключение которое мы
>    перехватили
>
>
> решение второй подзадачи приводит нас к двум вариантам.
>
> вариант №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 mailing list
> moscow-pm на pm.org | http://moscow.pm.org
>



-- 
Andrei Protasovitski
< andrei[dot]protasovitski[at]gmail[dot]com >
Diemen, Netherlands
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20130323/40cf4005/attachment-0001.html>


Подробная информация о списке рассылки Moscow-pm