WWW :: Mechanize :: GZip запускает сигнал __DIE__ ... почему? - PullRequest
0 голосов
/ 04 июня 2010

Мне потребовалось некоторое время, чтобы отследить внезапную проблему с моим кодом, но похоже, что WWW :: Mechanize :: GZip каким-то образом вызывает мой обработчик $ SIG { DIE }. Рассмотрим этот код:

use strict;
use WWW::Mechanize::GZip;

$SIG{__DIE__} = sub {
   print "WTF???  WHY IS THIS BEING TRIGGERED?\n";
};

my $mech = WWW::Mechanize::GZip->new();
$mech->get( 'http://ammoseek.com/' );

print $mech->content(), "\n";

Есть идеи, почему это происходит? И что я могу сделать, чтобы предотвратить это?

Спасибо

-Mike

Ответы [ 2 ]

2 голосов
/ 04 июня 2010

Вы можете узнать подробности того, что / как умерло, напечатав свой обработчик $SIG{__DIE__}:

  • Сообщение об ошибке ($_[0] в обработчике)

  • Трассировка стека (например, путем вызова Carp::cluck) из обработчика

В качестве альтернативы используйте параметр onerror => \&func для конструктора WWW :: Mechanize :: GZip, чтобы создать собственный обработчик ошибок (при условии, что ошибка не в Compress :: Zlib). От WWW :: Механизировать POD

onerror => \ & func

Ссылка на штамп, совместимый с функция, такая как Carp :: croak, то есть вызывается при фатальной ошибке.

Если установлено undef, ошибок нет когда-либо будет показано.

Если это значение не передано, мех использует Carp :: croak, если установлен Carp, или CORE :: умри, если нет.

Поскольку WWW :: Mechanize :: GZip является прямым подклассом WWW :: Mechanize, вы можете использовать те же параметры для конструирования в нем.

0 голосов
/ 04 июня 2010

Если предположить, что нет реального исключения, то есть код выполняется нормально без $SIG{__DIE__}, то где-то внутри этого вызова метода, вероятно, используется eval BLOCK для перехвата и восстановления после ошибки. Одна из нескольких проблем, связанных с использованием eval BLOCK в качестве обработчика исключений, заключается в том, что он вызывает $SIG{__DIE__}, хотя на самом деле не должен.

Чтобы избежать этого, убедитесь, что $ ^ S имеет значение false в вашем $SIG{__DIE__}.

local $SIG{__DIE__} = sub {
    return if $^S;

    ...your error catching code...
};

См. Perlvar для более подробной информации.

Кстати, вы можете узнать подробности исключения, которое вызывает это, напечатав @ _.

local $SIG{__DIE__} = sub {
    print "SIGDIE caught @_";
};

Еще лучше, если вам действительно не нужен глобальный обработчик кубиков, используйте eval BLOCK.

eval {
    my $mech = WWW::Mechanize::GZip->new();
    $mech->get( 'http://ammoseek.com/' );
    1;
} or do {
    die "WWW::Mechanize::GZip failed and said: $@";
};

И посмотрите на Try :: Tiny для лучшего обработчика исключений.

...