如果在它使用的模块中引发异常,我如何防止我的 perl 脚本终止?
Posted
技术标签:
【中文标题】如果在它使用的模块中引发异常,我如何防止我的 perl 脚本终止?【英文标题】:How can I prevent my perl script from terminating if an exception is thrown in a module it uses? 【发布时间】:2012-01-10 18:53:38 【问题描述】:我有一个 perl 脚本,使用标准的 Net::HTTP 代码和 perl 5.8.8。 我遇到了一个错误情况,当我调用时服务器返回 0 字节的数据:
$_http_connection->read_response_headers;
不幸的是,我的 perl 脚本 die
s,因为 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
,然后进入我自己的错误处理代码,而不是die
ing 本身?
我确信这是一个常见的情况,可能很简单,但我以前没有遇到过。
【问题讨论】:
【参考方案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 解释器来执行有问题的代码。
当然,自定义异常处理程序应该足以应付手头的任务。
【讨论】:
以上是关于如果在它使用的模块中引发异常,我如何防止我的 perl 脚本终止?的主要内容,如果未能解决你的问题,请参考以下文章