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块设置并处理本地化$@并处理其他边缘情况.

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...