外部リソース呼び出しを常に try-catch でラップする必要がありますか? (つまり、データベースまたはファイル システムへの呼び出し) 外部リソースを呼び出すときのエラー処理のベスト プラクティスはありますか?
6 に答える
処理できる例外のみをキャッチします。したがって、たとえば外部リソースを使用する場合のベストプラクティスは、処理できることがわかっている特定の例外をキャッチすることです。ファイルの場合、これは(IOException、SecurityExceptionなど)である可能性があり、データベースの場合、例外はSqlExceptionまたはその他である可能性があります。
いずれにせよ、処理しない例外をキャッチしないでください。処理できる上位層にそれらを流してください。または、何らかの理由で例外をキャッチしても処理しない場合は、throwだけを使用して例外を再スローします。(これにより、trowではなくrethrow IL opが作成されます)。
どのタイプの例外がスローされるかわからないリソースを使用する場合は、一般的な例外タイプをキャッチする必要があります。この場合、安全な方法は、(可能であれば)別のアプリドメインからの上記のリソースを使用するか、例外を表示またはログに記録できるトップレベル(UIなど)までバブルさせることです。
キャッチブロックを使用する理由は3つあると思います。
- 例外を処理して回復できます(「低レベル」コードから)
- 例外を再ラップしたい(ここでも、「低レベル」コードから)
- あなたはスタックの最上位にいて、操作自体を回復することはできませんが、アプリ全体がダウンすることは望ましくありません
これらに固執する場合、ブロックと比較してキャッチブロックは非常に少ないはずです。これらのtry/finally
ブロックtry/finally
はほとんどの場合Dispose
、単に呼び出しているだけなので、ステートメントとして記述するのが最適ですusing
。
finally
結論:リソースを解放するためのブロックを用意することは非常に重要ですが、catch
通常、ブロックはまれです。
それは私が見つけたものであり、それは私にとって理にかなっています。明らかなことを手動で確認し、残りはtry-catchに任せてください。
Eric Lippertは、これに関する優れたブログをここに持っています。
何か便利なことができない限り、例外をキャッチする意味はありません(「vexing」(ブログを参照)を除く)。そして、ほとんどの場合、単純にできないので、バブルさせます(UIは明らかに何かをクレンジングして表示する必要があります)。
ただし、リソース管理に対処するための「試行/最終」がある場合があります。または、さらにクリーンな、同じことを行うための「使用」ブロック。
それは常にあなたが達成したいことに依存します。サーバーが応答しない場合、ルーチンが実行していることをすべて停止するほど深刻である可能性があり、呼び出し元に例外をスローする必要があります。
それ以外の場合は、データベースの更新に失敗したかどうかは関係ありません。その後、例外を消費しても問題ありません。
明らかに、エンドユーザーにスタックトレースを表示したくないので、どこかでそれをキャッチする必要があります。
絶対的な答えは完全に条件付きだと思います (環境をどのように制御しているか、パフォーマンスと一貫性の間で期待されるバランスとは何か、そして他の多くのことは確かです) が、一般的に言えば、潜在的に遅いものよりも安全性を選択して、常にそうしています。パフォーマンス。