地元の漁獲がアンチパターンであるとは思わない。実際、私が正しく覚えていれば、それは実際にJavaで実施されている!
エラー処理を実装するときに私にとって重要なのは、全体的な戦略です。サービス境界ですべての例外をキャッチするフィルターが必要な場合、手動でインターセプトしたい場合があります。全体的な戦略があり、チームのコーディング標準に該当する場合は両方とも問題ありません。
個人的には、次のいずれかを実行できるときに、関数内のエラーをキャッチするのが好きです。
- コンテキスト情報(オブジェクトの状態や何が起こっているかなど)を追加します
- 例外を安全に処理する(TryXメソッドなど)
- システムがサービスの境界を越えて、外部ライブラリまたはAPIを呼び出しています
- 異なるタイプの例外をキャッチして再スローしたい(おそらく、元の例外を内部例外として)
- いくつかの低価値のバックグラウンド機能の一部として例外がスローされました
これらのケースのいずれでもない場合、ローカルのtry / catchを追加しません。そうである場合、シナリオに応じて、例外を処理する場合(たとえば、falseを返すTryXメソッド)または再スローして、例外がグローバル戦略によって処理されるようにします。
例えば:
public bool TryConnectToDatabase()
{
try
{
this.ConnectToDatabase(_databaseType); // this method will throw if it fails to connect
return true;
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
return false;
}
}
または再スローの例:
public IDbConnection ConnectToDatabase()
{
try
{
// connect to the database and return the connection, will throw if the connection cannot be made
}
catch(Exception ex)
{
this.Logger.Error(ex, "There was an error connecting to the database, the databaseType was {0}", _databaseType);
throw;
}
}
次に、スタックの上部でエラーをキャッチし、ユーザーにわかりやすいメッセージを表示します。
どちらのアプローチを採用するにしても、このシナリオの単体テストを作成する価値は常にあるため、機能が変更されないことを確認し、後日プロジェクトのフローを中断することができます。
どの言語で作業しているのかは言及していませんが、.NET開発者であり、これを見ないほど何度も見たことがあるでしょう。
書かないで:
catch(Exception ex)
{
throw ex;
}
使用する:
catch(Exception ex)
{
throw;
}
前者はスタックトレースをリセットし、トップレベルのキャッチをまったく役に立たなくします!
TLDR
ローカルでキャッチすることはアンチパターンではありません。多くの場合、デザインの一部であり、エラーにコンテキストを追加するのに役立ちます。