web-dev-qa-db-ja.com

例外を投げるvsロギング

次の方法でコーディングすることは良い習慣ですか?

try {
    //my code here
} catch (Exception e) {
    logger.error("Some error ", e);
    throw new MyCustomException("Some error ", e);
}

さらに、私は..

  • ロガーのみを使用しますか?
  • 例外のみをスローしますか?
  • 両方する?

throwを使用すると、コールスタックの別の部分で例外をキャッチできることを理解していますが、追加のロギングにはいくつかの隠れた利点があり、同様に便利です。

26
xrabbit

場合によっては、ロギングと例外のスローの両方を使用します。特に、APIで役立ちます。例外をスローすることで、呼び出し元が例外を処理できるようになり、ログを記録することで、その原因を自分で特定できます。

また、呼び出し元が同じシステムにある場合、すべてのキャッチにログを追加すると、重複したログが存在します。

10

通常、私はあなたがまたはの再スローをログに記録する必要があると主張します。両方を実行すると、すべてのレイヤーで例外が何度もログに記録されるため、ログが読みにくくなります。さらに悪いことに、実際に発生しているエラーの数を把握するのは困難です。それは7つのエラーでしたか、それとも同じエラーを記録したアプリの7つのレイヤーでしたか?

これは、例外を抑制する場合をログに記録し、再スローする価値がなかった理由を説明することを意味します。

一方、例外を再スローするの場合、それがキャッチされて抑制される(この場合、キャッチャーが例外をログに記録し、なぜ抑制されたのか)か、バブリングしますアプリの外に出て、アプリコンテナーにキャッチされます。これにより、例外がキャッチされ、ログに記録されます。すべての例外がログに一度だけ表示されます。

17
gustafc

提案するパターンを使用すると、通常、ログでエラーイベントが複数回報告されることになります。さらに、ログを読み取るときにそれらの間を接続するのは必ずしも簡単ではありません。

個人的には、エラーイベントを1回だけ記録し、それをより高いコールレベルで記録することを好みます。したがって、ログに記録して再スローすることはほとんどありません。私は通常、例外がなんらかの方法で処理できるコンテキストに到達するまでコールスタックを上に移動させ、ここでログを記録します。

例外がラップされ、正しくスローされた場合、単一のログメッセージのスタックトレースからコンテキストが完全に明確になるはずです。

5
Eyal Schneider

適切な答えは次のとおりです。

何かがうまくいかないことに対応しているので、一般的に、キャッチした例外をログに記録します。そのため、ソナーなどのコード分析ツールでは、ログに記録しないと警告が表示されます。

次のタスクを検討してください:ファイルの解析。ファイルを解析するとき、実際には各行を解析しようとします。場合によっては、一部の行の形式が正しくないことがあり、そのためにファイルの解析を停止したくない場合があります。その場合、おそらく間違った行をログに記録して、ファイルを続行したいと思うでしょう。ただし、ある時点で読み取り中にI/O例外が発生したとします(たとえば、他のプログラムがファイルにアクセスしているときにファイルを削除した場合など)。

この場合、発生したエラーをログに記録し、新しい例外をスローしてファイル全体の処理を停止することができます。

要するに、あなたは何をするのが最善かを考えなければなりません。しかし、どちらの方法も悪くありません。

1
Arnaud Potier

慎重にパターンを使用する必要があると思います。上記を記述したように、例外ごとに2つのスタックトレースをログに記録することになり、ログが過剰な情報でいっぱいになる可能性があります。

ロギングとスローについては、2つの個別の懸念事項があります。例外をスローすると、実行が中断され、それ以上の作業が妨げられます。データベースのコミットがロールバックされる可能性があります。ロギングは、情報をログファイル(または他の場所)にダンプするだけです。これはデバッグにさらに役立ち、多くの場合テストがはるかに困難になります。

1
Brian Agnew