Perl:在没有死的情况下捕获错误

前端之家收集整理的这篇文章主要介绍了Perl:在没有死的情况下捕获错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在玩错误处理并遇到一些问题.
我使用DBI模块连接数据库.

我通过使用一个我调用错误的子程序来进行自己的错误处理.

我可以捕获我自己的死并处理它们就好了但是当我的数据库连接失败时,DBI模块显然打印出它自己的死:

DBI connect(…) Failed: ORA-12154: TNS:could not resolve the
connect identifier specified (DBD ERROR: OCIServerAttach) at …

我怎么去抓这个?

我尝试使用$SIG {__ DIE__},如下所示:

local $SIG{__DIE__} = sub {
  my $e = shift;
  print "Error: " .$e;
};

这是在我的主文件底部,在这个文件中我也调用了我自己的模块中可用的connect子例程.我也尝试将这段代码放在我的模块的底部,但它仍然打印出没有的错误

Error:

在它面前.

解决方法

DBI connect(…) Failed: ORA-12154:
TNS:could not resolve the connect
identifier specified (DBD ERROR:
OCIServerAttach) at …

How would I go about catching this ?

要捕获并处理此级别的错误,请使用块形式的eval,“eval {…}”.这将捕获子代码中发生的任何骰子.如果eval块中的代码死掉,它将设置$@,并且该块将返回false.如果代码没有死,$@将被设置为”.

使用SIG {WARN}和SIG {DIE}的信号处理很麻烦,因为它们是全球性的,还有竞争条件要考虑(如果我在处理不同的信号时得到信号会发生什么?等等.传统问题基于信号的计算).您可能正在编写单线程代码,因此您不必担心多个事件调用死的并发问题,但有用户需要考虑(也许他会在您尝试打开DBI连接时发送SIGKILL )

在这种特定情况下,您使用的是DBI.使用DBI,您可以控制出现错误的情况,如果它应该死,警告或无提示失败,并等待您检查返回状态.

以下是使用eval {…}的基本示例.

my $dbh = eval { DBI->connect( @args) };
if ( $@ )
{
    #DBI->connect threw an error via die
    if ($@ =~ m/ORA-12154/i )
    {
        #handle this error,so I can clean up and continue
    }
    elsif ( $@ =~ m/SOME \s* other \s* ERROR \s+ string/ix )
    {
       #I can't handle this error,but I can translate it
        die "our internal error code #7";
    }
    else 
    {
      die $@; #re-throw the die
    }
}

以这种方式使用eval存在一些小问题,与$@的全局范围有关. Try::Tiny cpan页面有一个很好的解释. Try :: Tiny处理最小的Try / catch块设置并处理本地化$@并处理其他边缘情况.

猜你在找的Perl相关文章