0

コードの突然の問題を追跡するのに少し時間がかかりましたが、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";

なぜこれが起こるのか考えていますか?そして、それを防ぐために私は何ができますか?

ありがとう、

-マイク

4

2 に答える 2

2

$SIG{__DIE__}ハンドラーを印刷することで、何が/どのように死亡したかの詳細を確認できます。

  • エラー メッセージ ($_[0]ハンドラー内)

  • Carp::cluckハンドラ内からのスタック トレース (たとえば、 の呼び出しによる)

別の方法として、onerror => \&funcWWW::Mechanize::GZip コンストラクターへのパラメーターを使用して、カスタム エラー ハンドラーを作成します (エラーが Compress::Zlib からのものではないと仮定します)。WWWから::Mechanize POD

onerror => \&func

致命的なエラーが発生したときに呼び出される、Carp::croak などのダイ互換関数への参照。

これが undef に設定されている場合、エラーは表示されません。

この値が渡されない場合、Mech は、Carp がインストールされている場合は Carp::croak を使用し、インストールされていない場合は CORE::die を使用します。

WWW::Mechanize::GZip は WWW::Mechanize の直接のサブクラスであるため、同じパラメーターをそのコンストラクターに使用できます。

于 2010-06-04T17:30:23.600 に答える
0

実際の例外がないと仮定すると、つまり、コードが正常に実行され、$SIG{__DIE__}そのメソッド呼び出し内のどこかでeval BLOCKエラーをトラップして回復するために使用されている可能性があります。eval BLOCK例外ハンドラーとして使用する際のいくつかの問題の1つは、$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をご覧ください。

于 2010-06-04T18:33:15.447 に答える