【发布时间】:2011-01-22 05:38:39
【问题描述】:
如何检查导致脚本或eval 块终止的异常类型?
我需要知道错误的类型以及异常发生的位置。
【问题讨论】:
如何检查导致脚本或eval 块终止的异常类型?
我需要知道错误的类型以及异常发生的位置。
【问题讨论】:
惯用的 Perl 是我们要么忽略所有错误,要么捕获它们以记录或转发到其他地方:
eval { func() }; # ignore error
或:
eval { func() };
if ($@) {
carp "Inner function failed: $@";
do_something_with($@);
}
或(使用Try::Tiny - 查看该页面,了解您可能希望在 Perl 的内置异常处理中使用它的原因):
try { func() }
catch {
carp "Inner function failed: $_";
do_something_with($_);
};
如果要检查异常的类型,请使用正则表达式:
if ( $@ =~ /open file "(.*?)" for reading:/ ) {
# ...
}
行和文件也在那个字符串中。
这很糟糕,因为你必须知道确切的字符串。如果您真的想要良好的错误处理,请使用来自CPAN 的异常模块。
$@ 不必是字符串,它可以是对象。 Exception::Class 允许您声明和抛出 Java 风格的异常对象。您可以在抛出错误时传递任意信息(文件名等)并使用对象方法而不是正则表达式解析获取该信息 - 包括 file 和 行号 例外。
如果您正在使用不使用 Error::Exception 的第三方模块,请考虑
$SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
这会将所有错误转换为 Exception::Class 对象。
Error::Exception 为 Exception::Class 对象设置正确的字符串化。
【讨论】:
eval { blah }; if($@) { blah } 已损坏,因为 $@ 可以被对象析构函数破坏。使用eval { some_code(); 1 } or do { handle_exception() };,handle_exception 可以保证运行,但 $@ 可能会丢失。仍然有一些微妙的陷阱需要避免。这就是为什么,如果您想要简单的异常处理,Try::Tiny 是一个不错的选择。 TT 的文档介绍了 Perl 中的异常处理存在问题的方式。 search.cpan.org/perldoc?Try::Tiny您可能还想阅读stackoverflow.com/questions/2165161/…