1

アプリケーションの 1 つで Log4perl を使用しLog::Dispatch::Email、sendmail の特別な処理が必要なため、から継承する独自のアペンダーを作成しました。このアペンダーは数年前から機能していましたが、今日、$@Log4perl を自分のアペンダーまたは単にそれ自体を使用するように構成すると、以前のように設定されない奇妙な動作を認識しましたLog::Dispatch::Email。以前は次の方法でエラーをキャッチしていました。

eval { main(); 1; };
if (my $error = $@)
{
  log()->error($error);
  exit(error_no_success());
}
exit(error_success());

Log4perl 構成からメール アペンダーを削除し、アプリケーションがメインで停止すると$error、メッセージが取得され、代替内にログが記録されます。Log::Dispatch::Email問題は、この抽象基本クラスの独自の子孫を直接構成する$@と、上記のステートメントが空の文字列になり、以前と同じエラーが発生し、認識されなくなることです。のようなものを書くとeval {} or ... $@、適切に利用可能になり、保存できます。以下の作品:

my $error = undef;
eval { main(); 1; } or $error = $@;
my $error2 = $@;
if ($error)
{
  log()->error($error);
  exit(error_no_success());
}
exit(error_success());

$error2Log::Dispatch::Email何らかの方法で構成すると、常に空の文字列になります。もちろん、最初の例を使用し、以前は機能していたすべてのコードを 2 番目の例に変更したくはありません。

私の最初の例に何か問題がありますか? 私の観点からは、perldoc の eval について文書化されているように見え、電子メールのアペンダーなしで動作します。

メール アペンダーを使用する$@と、2 番目の例で Perl が設定する方法、タイミング、または設定内容が変化する理由を思いつきますか? 回避策はありますか?私はすでにソースを見てきましたがLog::Dispatch、私のコードに明らかに干渉しているものは見つかりませんでした。

ヒントをありがとう!

4

1 に答える 1

0

PerlMonksの助けを借りて、最終的に問題を発見しました: $@ は信頼できません。以前にも同様の問題があり、慣例によりすべてのデストラクタで $@ をローカライズしました。明らかに、デバッグ出力をログに記録していたものを見逃していました。ロギングステートメントの前にこのデストラクタで $@ をローカライズした後も、私の問題は解決され、エラートラップが再び機能しました。なぜ問題が Log::Dispatch を使用してのみトリガーされたのかはわかりません。なぜなら、デストラクタは以前に常にデバッグ ステートメントをログに記録していたからです。

于 2013-08-12T17:29:12.867 に答える