【问题标题】:WWW::Mechanize::GZip triggering __DIE__ signal...why?WWW::Mechanize::GZip 触发 __DIE__ 信号...为什么?
【发布时间】:2011-02-27 21:56:02
【问题描述】:

我花了一段时间才发现我的代码突然出现问题,但似乎 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";

知道为什么会这样吗?我能做些什么来预防它?

谢谢,

-迈克

【问题讨论】:

  • 传递给死的消息是什么?

标签: perl gzip mechanize die


【解决方案1】:

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

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

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

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

onerror => \&func

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

如果设置为undef,则没有错误 将永远显示。

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

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

【讨论】:

  • 不幸的是,将 onerror 设置为 undef 不起作用。我给模块作者 Peter Giessner 发了电子邮件,他建议我只需创建一个本地 $SIG{DIE} 以忽略所有 gunzip 错误...
  • 可能来自Compress::Zlib
  • @Mike:这也将忽略所有其他错误,除非您稍微自定义您的 DIE 处理程序。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2017-03-16
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2012-03-25
    相关资源
    最近更新 更多