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

对 die 兼容函数的引用,例如 Carp::croak,当出现致命错误时调用该函数。

如果将其设置为 undef,则不会显示任何错误。

如果没有传递这个值,如果安装了 Carp,Mech 使用 Carp::croak,如果没有安装,则使用 CORE::die。

由于 WWW::Mechanize::GZip 是 WWW::Mechanize 的直接子类,因此您可以在其中的构造函数中使用相同的参数。

于 2010-06-04T17:30:23.600 回答
0

假设没有真正的异常,也就是说,代码在没有 的情况下正常运行$SIG{__DIE__},那么该方法调用内部的某处可能eval BLOCK用于捕获错误并从错误中恢复。eval BLOCK用作异常处理程序的几个问题之一是它会触发$SIG{__DIE__},即使它确实不应该触发。

为避免这种情况,请检查 $^S 在您的$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 回答