DBI connect(...)が失敗しました:ORA-12154:TNS:指定された接続識別子(DBDエラー:OCIServerAttach)を解決できませんでした...
これをどうやって捕まえるの?
このレベルのエラーをキャッチして処理するには、ブロック形式のeval「eval{...}」を使用します。これにより、サブコードで発生するすべてのダイがキャッチされます。evalブロック内のコードが停止すると、$ @が設定され、ブロックはfalseを返します。コードが終了しない場合、$@は''に設定されます。
SIG{WARN}およびSIG{DIE}を介した信号処理の使用はグローバルであるため面倒であり、考慮すべき競合状態もあります(別の信号を処理しているときに信号を受信するとどうなりますか?など。信号ベースのコンピューティング)。おそらくシングルスレッドコードを書いているので、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 :: Tinycpanページにはすばらしい説明があります。Try :: Tinyは、最小限のTry / catchブロック設定を処理し、$@のローカライズとその他のエッジケースの処理を処理します。