エラー処理の実装方法[終了]


13

私は数年間プロレベルでプログラミングを行ってきましたが、それでもエラー処理を完全に理解していません。私のアプリケーションは正常に動作しますが、エラー処理は専門的なレベルでは実装されておらず、多くの手法の組み合わせです。

エラー処理の背後に構造はありません。プロレベルでどのように実装されているかを学び、理解したいと思います。これは、私が知識を欠いている分野の1つです。

ロジックフローでチェックするために、いつ例外を使用し、成功ステータスを返す必要がありますか?例外を組み合わせてステータスを返すことはできますか?

主にC#でコーディングします。


2
なぜ反対票ですか?エラー処理の実装とその方法について深刻な質問をしています。これがプログラマーの間でこのような質問をするのに最適な場所ではない場合、どこにありますか?そのような質問をする場所が他にないので、人々がそのような質問を下票するとき、それは本当に私を悩ませます。おそらく、信頼できる回答と可能なリソースを得るためのウェブ上の唯一の場所です。だから、他の人が間違いなくGoogleに答えるという質問に投票するのではなく、答えることは簡単ではないでしょうか?
ジェームズジェフリー

6
あなたの質問は非常に広範です。おそらく、コーディングの目標を達成できなかった特定の例を関連付けることで、範囲を狭めることができます。
アンディズスミス

エラー処理に関する多くの記事がWeb上にあります。これを試してください:msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

回答:


25
  1. 例外的なもの、あなたがあまりにも頻繁に遭遇することを合理的に期待できないもの、何かがうまくいかないことを示すものには例外を使用してください。たとえば、ネットワークがダウンしている場合、それはWebサーバーにとって例外的なものです。データベースが利用できない場合、何かが間違っていることを意味します。構成ファイルが欠落している場合、おそらくユーザーがそれを台無しにしたことを意味します。

  2. 不正なコードを処理するために例外を使用しないでください。コードの正確性を確認するには、アサーションを使用するか、.NET Framework 4以降では、コードコントラクト(アサーションを置き換え、追加の特に価値のある機能)を使用する必要があります。

  3. 例外的でない場合には例外を使用しないでください。ユーザーが数字の入力を求められたときに「犬」と入力したという事実は、例外に値するほど例外的ではありません。

  4. 例外のタイプを選択するときは注意してください。必要に応じて独自のタイプを作成します。親を捕まえると子供も捕まえることに留意して、継承を慎重に選択しました。決してthrow Exception

  5. エラーに戻りコードを使用しないでください。エラーコードは簡単にマスクされ、無視され、忘れられます。エラーがある場合は、エラーを処理するか、上位スタックに伝播します。

  6. メソッドがエラーを返すことが予想され、エラーが例外的でない場合は、エラー番号ではなく列挙型を使用してください。例:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    、などの意味はLoadOperationResult.ServerUnavailableLoadOperationResult.ParsingErrorたとえば、コード12はサーバーがダウンし、コード13はデータを解析できないことを意味することを思い出すよりもはるかに明確です。

  7. 特定のドメインで働くすべての開発者が知っている一般的なコードを参照する場合は、エラーコードを使用します。たとえば、HTTP 404 Not FoundまたはHTTP 500 Internal Server Errorの列挙値を再作成しないでください。

  8. ブール値に注意してください。遅かれ早かれ、特定のメソッドが成功したか失敗したかだけでなく、その理由を知りたくなるでしょう。そのためには、例外と列挙型がはるかに強力です。

  9. すべての例外をキャッチしないでください(スタックの最上位にいる場合を除く)。例外をキャッチしたら、それを処理する準備ができているはずです。すべてをキャッチすることは、コードが正しく実行されるかどうか気にしないことを示しています。これにより、「今はこれを修正する方法を検索したくない」が解決するかもしれませんが、遅かれ早かれあなたを傷つけます。

  10. C#では、次のような例外を再スローしないでください。

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    スタックを壊しているからです。代わりにこれを行います:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. 例外メッセージを書くときは努力してください。throw Exception("wrong data")またはのようなものを見た回数throw Exception("shouldn't call this method in this context")。6か月後の自分自身を含む他の開発者は、どのデータが間違っているのか、コンテキストでメソッドを呼び出すべきではない理由、または正確にどのコンテキストを呼び出すべきなのかを知りません。

  12. ユーザーに例外メッセージを表示しません。それらは普通の人には期待されておらず、多くの場合、開発者自身にとっても読めません。

  13. 例外メッセージをローカライズしないでください。ローカライズされたメッセージのドキュメントを検索するのは大変で無意味です。すべてのメッセージは英語と英語のみである必要があります。

  14. 例外とエラーだけに集中しないでください。ログも非常に重要です。

  15. .NETでは、メソッドのXMLドキュメントに例外を含めることを忘れないでください。

    /// <exception cref="MyException">Description of the exception</exception>

    XMLドキュメントに例外を含めると、ライブラリを使用している人にとって物事がずっと簡単になります。メソッドによってスローされる可能性のある例外とその理由を推測しようとする以上に迷惑なことはありません。

    この意味で、Java例外処理は、より厳密で優れたアプローチ提供します。呼び出されたメソッドによってスローされる可能性のある例外を処理するか、処理しない例外をスローできることを独自のメソッドで宣言して、物事を特に透過的にします。


¹これは言われていますが、例外とエラーのJavaの区別は、言語がチェック済みと未チェックの例外を持っていることを考えると、かなり役に立たず、混乱を招きます。幸いなことに、.NET Frameworkには例外のみがあり、エラーはありません。


私はこれから少し引用を学びました、リストがどこから来たのか尋ねてもいいですか?サイトまたは個人的な経験?いずれにせよ例外的な仕事(彼はそれを手に入れた?)。
Shelby115

@ Shelby115:リストは、スタック交換、個人的な経験、およびSteve McconnellによるCode Completeの順にリストされています。
アルセニムルゼンコ

@MainMa、ありがとうございます!私は大学にいたときにCode Completeを所有していましたが、誰かがそれを盗みました。私はそれを読むことができませんでした。
ジェームズジェフリー

@JamesJeffery:それから図書館で第2版を借りるか、それを購入します。これは、開発に関連した珍しい本の1つであり、完全にお金の価値があります。
アルセニムルゼンコ

DIも独自のクリーンコードを、そして完全に第7章忘れ:@MainMaだけでは、アマゾンからの感謝を命じた
ジェームズ・ジェフリー

1

MainMaのリストは非常に完全だと思います。私は自分のいくつかを追加します:

  1. Eric Lippertの例外の分類方法に関する記事を読んでください。特に重要なのは、実際にはコードのバグである例外をキャッチしないという彼のポイントです。代わりにコードを修正してください!
  2. 例外が発生する可能性があることがわかっており、それに対して何かを行うことができる場合、それを処理しますが、try-catchのスコープを制限し、期待する特定の例外をキャッチします。つまり、これをしないでください:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

代わりにこれを行います:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • 制御フローに例外を使用しないでください。たとえば、ルックアップダイアログでClientNotFoundExceptionをスローしないでください(この状況では、クライアントが見つからないことは例外ではありません)。

  • 例外を飲み込まないでください!

  • 本当に例外を処理できるのは、次の3つのことだけを意味することに注意してください。

    1. 操作を再試行してください。問題が一時的なものである場合にのみ有効です。
    2. 別の方法を試してください。
    3. 問題について誰かに通知します。通知がアクション可能である場合にのみ有効です。つまり、ユーザーが通知について何かできることを意味します。

    これらのオプションのいずれも当てはまらない場合、おそらくその例外をキャッチすべきではありません。ただし、ログに記録してから、操作をキャンセルするかシャットダウンする必要があります。もちろん、これは、正確性と堅牢性に関する要件に依存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.