【问题标题】:How do I test for an exception type in perl?如何在 perl 中测试异常类型?
【发布时间】:2011-01-22 05:38:39
【问题描述】:

如何检查导致脚本或eval 块终止的异常类型? 我需要知道错误的类型以及异常发生的位置。

【问题讨论】:

标签: perl eval exception die


【解决方案1】:

Perl 方式

惯用的 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/…
  • 我已经更新了答案,包括 Try::Tiny,以防万一有新人偶然发现。
猜你喜欢
  • 2018-02-13
  • 2019-07-27
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多