如何在perl中测试异常类型?

pla*_*etp 8 perl eval exception die

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

rjh*_*rjh 13

Perl的方式

Idiomatic Perl是我们要么忽略所有错误,要么捕获它们以便记录或转发到其他地方:

eval { func() };  # ignore error
Run Code Online (Sandbox Code Playgroud)

要么:

eval { func() };
if ($@) {
    carp "Inner function failed: $@";
    do_something_with($@);
}
Run Code Online (Sandbox Code Playgroud)

或者(使用Try :: Tiny - 查看该页面,了解您可能希望在Perl的内置异常处理中使用它的原因):

try { func() }
catch {
     carp "Inner function failed: $_";
     do_something_with($_);
};
Run Code Online (Sandbox Code Playgroud)

如果要检查异常类型,请使用正则表达式:

if ( $@ =~ /open file "(.*?)" for reading:/ ) {
    # ...
}
Run Code Online (Sandbox Code Playgroud)

行和文件也在该字符串中.

这是非常讨厌的,因为你必须知道确切的字符串.如果您真的想要良好的错误处理,请使用CPAN中的异常模块.

异常:类

$ @不必是字符串,它可以是一个对象.Exception :: Class允许您声明并抛出Java样式的异常对象.您可以在抛出错误时传递任意信息(文件名等),并使用对象方法而不是正则表达式解析来获取该信息 - 包括异常的文件行号.

如果您使用的是不使用Error :: Exception的第三方模块,请考虑

$SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
Run Code Online (Sandbox Code Playgroud)

这会将所有错误转换为Exception :: Class对象.

Error :: Exception为Exception :: Class对象设置正确的字符串化.

  • `eval {blah}; if($ @){blah}`被破坏是因为`$ @`可以被对象析构函数破坏.使用`eval {some_code(); 1}或do {handle_exception()};`handle_exception保证运行,但$ @可能会丢失.还有一些微妙的陷阱需要避免.这就是为什么,如果你想要简单的异常处理,`Try :: Tiny`是一个很好的方法.TT的文档探讨了Perl中的异常处理存在问题的方法.http://search.cpan.org/perldoc?Try::Tiny您可能还想阅读http://stackoverflow.com/questions/2165161/whats-broken-about-exceptions-in-perl (6认同)