WWW::Mechanize::GZip 触发 __DIE__ 信号...为什么?

发布于 2024-09-04 10:39:02 字数 422 浏览 7 评论 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";

知道为什么会发生这种情况吗?我能做些什么来预防它?

谢谢,

-迈克

It's taken me a while to track down a sudden problem with my code, but it appears that WWW::Mechanize::GZip is somehow triggering my $SIG{DIE} handler. Consider this code:

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";

Any idea why this would be happening? And what can I do to prevent it?

Thanks,

-Mike

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千鲤 2024-09-11 10:39:02

您可以通过让 $SIG{__DIE__} 处理程序打印来了解死亡原因/原因的详细信息:

  • 错误消息(处理程序中的$_[0]

  • 处理程序中的堆栈跟踪(例如通过调用Carp::cluck) p>

作为替代方案,使用 onerror => \&func 参数传递给 WWW::Mechanize::GZip 构造函数来创建自定义错误处理程序(假设错误不是来自 Compress::Zlib)。来自 WWW::Mechanize POD

错误=> \&函数

参考模具兼容
函数,如 Carp::croak,即
当出现致命错误时调用。

如果设置为 undef,则不会出现错误
将永远显示。

如果未传递该值,Mech 将使用
Carp::croak(如果安装了 Carp),或者
CORE::如果没有就死。

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

You can find out details of what/how died by having your $SIG{__DIE__} handler print:

  • Error message ($_[0] in the handler)

  • Stack trace (e.g. by calling Carp::cluck) from within the handler

As an alternative, use onerror => \&func parameter to WWW::Mechanize::GZip constructor to create custom error handler (assuming the error is not from Compress::Zlib). From WWW::Mechanize POD

onerror => \&func

Reference to a die-compatible
function, such as Carp::croak, that is
called when there's a fatal error.

If this is set to undef, no errors
will ever be shown.

If this value is not passed, Mech uses
Carp::croak if Carp is installed, or
CORE::die if not.

Since WWW::Mechanize::GZip is a direct subclass of WWW::Mechanize, you can use the same parameters to constructor in it.

殊姿 2024-09-11 10:39:02

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

为了避免这种情况,请检查 $SIG{__DIE__} 中的 $^S 是否为 false。

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 以获得更好的异常处理程序。

Assuming there isn't a real exception, that is, that the code runs normally without the $SIG{__DIE__}, then something, somewhere inside that method call is probably using eval BLOCK to trap and recover from an error. One of several problems with using eval BLOCK as an exception handler is that it triggers $SIG{__DIE__} even though it really shouldn't.

To avoid this, check that $^S is false in your $SIG{__DIE__}.

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

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

See perlvar for more details.

BTW You can discover the details of the exception which is triggering this by printing @_.

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

Better yet, unless you really need a global die handler, use eval BLOCK.

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

And have a look at Try::Tiny for a better exception handler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文