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

问题描述 投票:34回答:4

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

我想知道如何做到以下几点

try {
    // do something that will fail!

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

如何获得错误的打印与堆栈跟踪?

perl error-handling try-catch
4个回答
54
投票

你可能最好使用 尝试::Tiny 这将帮助你避免一些 陷阱与老年 perls.

use Try::Tiny;

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

45
投票

据我所知 错误 已被废弃。 但这里你可以不用那个模块来做。

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

基本上,使用 评价 而不是 try, 死亡 而不是 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那么标准的trycatch方法是这样的(直接来自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." }
}

为了获得堆栈跟踪,请看 鲤鱼.


8
投票

如果你想要一些比Try::Tiny更强大的东西,你可能会想尝试看看 TryCatch 模块在CPAN中。


0
投票

不幸的是 TryCatch 在新的0.006020版本中被破坏了。开发::Declare 并且似乎没有打算修复它。perl核心开发团队也抱怨TryCatch依靠那些时髦的东西来工作。

取而代之的是一个新的实现,叫做 尼斯::尝试,这是一个完美的替代品。

不需要像Try::Tiny那样在最后的括号中使用分号。

你也可以做异常变量赋值,比如

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

它也可以使用类异常,如

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

而且它还支持 finally. 它的功能设置使其相当独特。

完全公开:当TryCatch被破坏时,我已经开发了这个模块。

© www.soinside.com 2019 - 2024. All rights reserved.