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