如何正确使用error.pm提供的perl中的try catch?

时间:2012-04-26 23:35:54

标签: perl error-handling try-catch

我发现有一个模块Error提供try和catch功能,就像在java中一样。但我对如何打印返回的异常感到困惑。

我想了解如何执行以下操作

try {
    // do something that will fail!

} catch (Error e) {
    // Print out the exception that occurred
    System.out.println(e.getMessage());
}

如何使用堆栈跟踪打印错误?

5 个答案:

答案 0 :(得分:51)

使用Try::Tiny可能会更好,这可以帮助您避免使用pitfalls with older perls

use Try::Tiny;

try {
        die "foo";
} catch {
        warn "caught error: $_";
};

答案 1 :(得分:44)

我上次检查,Error已被弃用。但是如果没有那个模块,你就会这样做:

eval {
    die "Oops!";
    1;
} or do {
    my $e = $@;
    print("Something went wrong: $e\n");
};

基本上,使用eval代替trydie代替throw,并在$@中查找异常。 eval块末尾的真实值是防止$@在早于5.14的Perl版本中再次使用之前无意中更改的习惯用法的一部分,有关详细信息,请参阅P::C::P::ErrorHandling::RequireCheckingReturnValueOfEval。例如,此代码存在此缺陷。

# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14
eval {
    die "Oops!";
};
if (my $e = $@) {
    print("Something went wrong: $e\n");
}
# BAD, DO NOT USE WITH PERLS OLDER THAN 5.14

但请注意,许多Perl操作在失败时不会引发异常;他们只是返回一个错误代码。对于内置和标准模块,可以通过autodie更改此行为。如果您正在使用autodie,那么执行try / catch的标准方法是这样的(直接来自autodie perldoc):

use feature qw(switch);

eval {
   use autodie;

   open(my $fh, '<', $some_file);

   my @records = <$fh>;

   # Do things with @records...

   close($fh);

};

given ($@) {
   when (undef)   { say "No error";                    }
   when ('open')  { say "Error from open";             }
   when (':io')   { say "Non-open, IO error.";         }
   when (':all')  { say "All other autodie errors."    }
   default        { say "Not an autodie error at all." }
}

要获得堆栈跟踪,请查看Carp

答案 2 :(得分:5)

如果你想要比Try :: Tiny更强大的功能,你可能想尝试查看CPAN中的TryCatch模块。

答案 3 :(得分:0)

不幸的是,TryCatch已被Devel::Declare的新版本0.006020破坏,并且似乎无意对其进行修复。 Perl核心开发人员团队还抱怨TryCatch依靠其来实现其时髦功能。

相反,有一个名为Nice::Try的新实现,可以完美替代。

没有必要在最后一个括号上使用半冒号,例如Try :: Tiny。

您也可以像这样进行异常变量分配

  try
  {
    # something
  }
  catch( $e )
  {
    # catch this in $e
  }

它也可以使用类异常(如

)工作
  try
  {
    # something
  }
  catch( Exception $e )
  {
    # catch this in $e
  }

它还支持finally。它的功能集使其非常独特。

完全公开:TryCatch损坏时,我已经开发了此模块。

答案 4 :(得分:0)

恕我直言,在大多数情况下,Syntax::Keyword::Try 是比 Try::Tiny 更好的选择。

Try::Tiny 比 eval 或 Syntax::Keyword::Try 慢一个数量级。这是否有问题取决于您的应用程序。对于许多应用程序来说,它并不重要。

此外,如果您是来自其他语言的访问者,Try::Tiny 具有语法怪癖,这使其与您习惯的 try/catch 不同。

相关问题