【问题标题】:How can I prevent my perl script from terminating if an exception is thrown in a module it uses?如果在它使用的模块中引发异常,我如何防止我的 perl 脚本终止?
【发布时间】:2012-01-10 18:53:38
【问题描述】:

我有一个 perl 脚本,使用标准的 Net::HTTP 代码和 perl 5.8.8。 我遇到了一个错误情况,当我调用时服务器返回 0 字节的数据:

$_http_connection->read_response_headers;

不幸的是,我的 perl 脚本 dies,因为 Net::HTTP::Methods 模块在第 306 行有一个“死”:

Server closed connection without sending any data back at
/usr/lib/perl5/vendor_perl/5.8.8/Net/HTTP/Methods.pm line 306

当然,第 305-307 行是:

unless (defined $status) {
die "Server closed connection without sending any data back";
}

我怎样才能让我的脚本从这种情况“正常恢复”,检测到die,然后进入我自己的错误处理代码,而不是dieing 本身?

我确信这是一个常见的情况,可能很简单,但我以前没有遇到过。

【问题讨论】:

    标签: perl exception-handling die


    【解决方案1】:

    使用eval 捕捉异常can occasionally be problematic,尤其是5.14 之前的版本。你可以使用Try::Tiny

    【讨论】:

    • 我无法在这个系统上安装模块,这是我试图解决的一个罕见问题,所以“eval”现在必须做,但我会保留 Try::Tiny考虑到其他项目。谢谢。
    • 如果您可以在该系统上放置脚本,您也可以在该系统上使用Try::Tiny,即使您只是复制 &将模块源代码粘贴到您的脚本中。
    • 技术上肯定,但不值得付出努力,因为这个小内部脚本将解决大量问题。即使它由于 Net::HTTP 问题而死,也只是我们是否在自己死之前记录问题。如果我们错过了它,那也不是世界末日。 :)
    【解决方案2】:

    您可以使用eval { } 来捕获die() 异常。使用$@ 检查抛出的值:

    eval {
        die "foo";
    };
    print "the block died with $@" if $@;
    

    详情请见http://perldoc.perl.org/functions/eval.html

    【讨论】:

    • 在 Perl 5.14 之前,eval 最好写成 my $success = eval { code_that_may_die(); 1; }; if (!$success) { print "Error: $@" } 这是由于一个相当罕见的问题,即在退出 eval 块时,$@ 的值可能会被清除。从 5.14 开始,任何一种方式都可以使用。
    【解决方案3】:

    die 自定义为其他含义很简单:

    sub custom_exception_handler { ... } # Define custom logic
    
    local $SIG{__DIE__} = \&custom_exception_handler;  # Won't die now
    # Calls custom_exception_handler instead
    

    eval 相比,这种方法的最大优势在于它不需要调用另一个 perl 解释器来执行有问题的代码。

    当然,自定义异常处理程序应该足以应付手头的任务。

    【讨论】:

      猜你喜欢
      • 2010-11-19
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      相关资源
      最近更新 更多