うでない例外をキャッチ、または例外をスローすることになる。
-
21-08-2019 - |
質問
私を扱うインスタンスがいを投げ/rethrow例外であるということはコードの周辺での特定の例外です。ではありませていただけるため、例外がスローされることならない。
少なくとも、例外をキャッチ?
例外を直ちに中止しなければならないその取り扱い。ねというまったいわざわざおか。
解決
アプリケーションの場合は主として使用される他のお客様は単独では意味がある場合は例外をスロー状態が生じないか又は行わない)、ある賢明な画面でも正常に動作するように回復します。お客様で決めたい、というよう対応できるという例外がスロー.
一方、アプリケーションの場合は は の評価項目では、例外的な通知メカニズムを知る人もってものすごく間違っています。この場合、も検討しなければならないくつかの:
どのように稼働させ続けになりますか。はこのエラーは本当に復元できない? 例外をスローすと終了プログラムにはないものとなっているスペースシャトルをご利用いただけます。
ご使用の例外としてプリロギング? がほとんどない理由がないこ検討リロギング機構です。は例外をキャッチし、この例外のロガーにどのような動作するように、が起こりました。
あけましておめでとうございま伝えたいのを投入することにより、例外の理由を教えてください。 自分自身に尋ね価値とは何かということを投げた原因を使用して新規例外は、注意深く考えるかというものはありませんと良いと考えている。
なく、この例外が休資源の悪い状態です。 かない場合には優雅に口ということに関しては一般的な清掃します。だかやっている場合に必要なことだいくので、少なくとも考えら
try-finally
ブロックできますのでいくつかの後片付けます。
他のヒント
が非常に良いルールがかながら前:
例外がスローされた場合の方法はできないと思います。
この例外は何かが間違っています。きの実施の方法でおこない現代的な内装に変わ責任を認識するかどうかに正しく使われています。るかどうかのコードを使用方法漁獲物の例外ではないお客様の責任、責任の一人様ご利用方法です。
別のルールに従うには:
な例外をキャッチしないと知りたいです。
明らかだの清掃活動コードtry...finallyブロックございますのでご注意下さいんだけ例外をキャッチを捕獲します。やってはいけません飲み込み例外を黙々と.がある場合がありますの全ての例外(例えばによってcatch(Exception ex)クライアントまで、フルのC#)は、これらはかなり珍しくは、一般には特定の技術的理由です。例えば、ご利用の際に、スレッドです。NET framework2.0以降では、場合には例外エスケープからのスレッドでの原因となりま全体のアプリケーション-ドメインをアンロード.しかしながら、最小限でログインする必要がありますの例外の詳細エラーとして説明します。
一般的に、確実に初回のお申し込み な キャッチします。けられることも少なくないので、その回復から例外が必要とのビジネスルールのか、けられることも少なくないので、ビジネスルール定義されていないものです。場合は"取扱い"を除く、募金型その性能に著しい変化は見られる明事業規則おおります。良くない。
一般にパターンの追毎の例外を捕捉するより頭痛んできます。で起こる人を何らかの汎用例外処理コードアプリケーションを通じて全ての得て、最終的に隠れていバグを作る行為は不要.(ちなみにキャッチし、その後はrethrowingは悪化させます。)
でも、今までのことだけではなく: "しいただいてもかまいません例外をキャッチ?"
確かに。たとえば、あなたはJavaで文字列にいくつかのバイトをロードしようとしている場合:
try {
String myString = new String(byteArray, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Platform doesn't support UTF-8? What is this, 1991?
throw new RuntimeExceptione(e);
}
この場合、縮退がない、プラットフォームは、単に所望の動作をサポートすることができません。あなたは、初期化時に、この条件のためにあなたが望むすべてをチェックすることができますが、文字列のコンストラクタは、まだこの例外をスローし、そしてあなたはそれに対処する必要があります。どちらか)(つまり、またはCharset.forNameを使用します)。
ここでのことだ...それは「レイヤー」、または「カプセル化」、または「低カップリング」についてです。あなたのコードベースでいくつかの場所で、あなたが何かをする方法を書いています。それは公共の方法だと言います。したがって、それは多くの仮定や、発信者については何もないはず...むしろ、それは単に仕事をする必要があり、それは関係なく、それを呼び出すと、呼び出し元がでどのような文脈でいる人の、行うことになっている。
そして、いくつかの理由で、それはそのジョブを完了することができない、場合、それは「申し訳ありませんが、私はそれを行うことができませんでしたし、ここに理由です」、発信者に通知する必要があります。例外は、それが(ない唯一のメカニズムが、私が今までほとんどの場合のために見た中で最高のメカニズム)という呼び出し側を言わせするための優れたメカニズムです。
あなたが例外をスローするとき、ですから、あなたがパブリックメソッドを露出しているので、それは...キャッチされるか否か見当がつかないし、あなたは、なぜそれを呼び出すとすることを選択するかもしれない考えを持っていません。
例外のキャッチは、「文脈」の仕事です。たとえば、あなたが例外をスローする可能性がありますpublicメソッドで、ライブラリを書いていると言います。次に、あなたがWindowsフォームアプリケーションからそのライブラリを使用していると言います。 Windowsはアプリが例外をキャッチし、ユーザーにメッセージボックスが表示される場合がありますフォームます。
しかし、その後、あなたがWindowsサービスから同じライブラリを使用する場合があります。サービスは、例外をキャッチし、それをログに記録し、元の発信者にエラーを返すが、それは更なる要求を処理できるように走り続ける可能性が高いでしょう。
だから、例外は、発信者とプロバイダ間の契約上の合意のようなものです。プロバイダは、「あなた自身のビジネスがあるから、あなたは何をすべきか。私が仕事をするか、なぜ私はできない、あなたを教えてあげるのいずれか。」、と言いますそして、呼び出し側は、「あなたが仕事をすることができない場合はOK、ちょうど私に理由を教えて、と私はそのような場合に何をすべきかを決定ましょう。」と言う。
しかし、あなたはそれがキャッチされないことを知って、例外をスローするのでしょうか。
任意の時間があります
私は、あなたが手動で例外をスローしている場合、それがキャッチされる場合は、ほとんどの時間は、あなたが知っていないと言うでしょう。あなたは知っていたならば、あなただけの最初の場所で例外を投げるのではなく、それを自分で扱うことができるキャッチされるだろう。
公平を期すために、私はそれはあなたがやっている番組の種類に部分的に依存し、時には同じプログラマがライブラリと言っライブラリを消費コードの両方を構築し終わると仮定します。
あなたが期待していなかった場合は、あなたは、例外をキャッチしませんか?
/例外がスローされる可能性を認識していませんでした。しかし、脇にそれを入れて、時にはあなたは1層でそれについて知っているが、次の階層までを知って、あなたは例外を認識していると仮定すると、それを処理するためのより適切な場所です。
これは、アプリケーションの種類によって異なります。 Webアプリケーションは、例外は実行コンテキストまで泡立てた後も実行を継続することができます。
あなたはそれを扱うことができないレベルで例外をキャッチした場合、それはスロー/再スロー "例外に一般的に行われています。しかし、あなたはほとんど常にそれがキャッチされ、再スローされたと言うことで、より高いレベルでいくつかのログを追加する非常に少なくとも、問題にコンテキストを追加することになります。
例
Aは、Bは、C(例外をスロー)
を呼び出し、呼び出しBキャッチ/再スロー
Aキャッチます。
この場合、あなたはBの生成とエラーを投げ、およびCの生成とエラーを投げ区別できるように、Bは、いくつかのログを追加したいと思います。それはあなたに後で問題をデバッグして修正するより大きな能力を可能にする。
一般的に、あなたのプログラムを殺すために例外をしたいことはほとんどないでしょう。ベストプラクティスは除いてキャッチして適切に終了することです。これは、現在開いている情報を保存し、それらが破損しないように使用されているリソースを解放することができます。あなたが終了する場合、あなたは致命的な例外をキャッチしたときに、あなたがやっていたものが含まれ、独自の「コアダンプの情報のレポートを作成することができます。
あなたは例外があなたのプロセスを強制終了させた場合は、は、カスタム仕立てクラッシュ情報を手に入れるチャンスを排除している、とあなたはまた、あなたがフレンドリーエラーメッセージとし、終了をユーザーに提供する部分を飛ばしています。
だから、私は常に例外をキャッチし、決して自発的にそれらをあなたのプログラムに逆上して実行させることをお勧めします。
編集
あなたは、ライブラリを作成している場合、、あなたの関数が例外をスロー、または例外安全であるかどうかを事前に選択する必要があります。そのような場合には、時にはあなたは例外をスローし、発呼者がそれをキャッチするかどうか分からないでしょう。しかし、その場合には、それをキャッチしている限り、API関数が例外を投げることができることを宣言して、あなたの責任ではありません。 (私は「おそらくスロー例外を可能性」という意味の単語を探しています...誰もがそれが何であるかを知っていますか?それは私のすべての日のバグになるだろう。)
まず、絶対に例外をキャッチしない方が良いです状況があります。
時々、例外は時々、あなたのプログラムが不明な状態であることを伝えることができます。これはかなり本質的に真の例外の型指定された例外の数があります。 NullReferenceException
は、基本的に「バグがある」を示しています。そして、このような例外をキャッチすることによって、あなたは、短期的にはいいですねバグを隠すかもしれないが、長期的には、あなたはそれを修正するために幸せになると思います。製品がクラッシュしないかもしれないが、それは確かに予想される動作を持っていません。
しかし、これは私たち自身のために考案した例外の種類についても同様です。時には、例外Aがスローされたという事実は、「不可能」であるべき - と、まだそれが起こっているので、バグがあります。
。 あなたは例外をキャッチしたときにまた、非常に重要な何かが起こります(それが呼び出すと何でも)tryブロック内の全コールスタックのためのfinally
ブロックが実行されます。これらのfinallyブロックは何をしますか?まあ、何でも。プログラムが不明な状態にある場合と、私は本当に、の何でもの意味です。彼らは、ディスクからの貴重な顧客データを消去することができます。彼らはより多くの例外をスローすることができます。彼らは診断がバグが不可能なメモリ内のデータが破損、作ることができます。
だから、あなたは任意のより多くのコードを実行したくないので、あなたが行うものは何でも、のの例外をキャッチしません。それは過去に飛んでみよう、とあなたのプログラムは無害終了すると、Windowsエラー報告は、問題が最初に検出されたときにそれがあったように、プログラムの状態をキャプチャすることができるようになります。あなたは例外をキャッチした場合、あなたはさらに、プログラムの状態を台無しになる、実行するためのより多くのコードが発生します。
第二に、あなたはそれがキャッチされることはありません知って例外をスローする必要がありますか?私はその質問には、再利用可能な方法の本質を誤解だと思います。この方法の全体的なアイデアは、それが次のことを「契約書」を持っているということです。これは、特定のパラメーターを受け入れ、一定の値を返し、プラスにもそれは一定の条件の下で一定の例外をスローします。それは契約だ - それは、彼らはそれで何をすべきか、呼び出し側の責任です。一部の発信者のために、例外Aは、回復可能な状態を示している可能性があります。他の発信者の場合は、バグを示している可能性があります。そして、私は上記の言ったことから、それは例外がバグを示す場合には、は、それがキャッチされてはならないことは明らかである。の
そして、あなたは、これはマイクロソフトエンタープライズライブラリの例外のために何を意味するのか迷っている場合ブロックを取り扱い:はい、それはかなり壊れています。彼らはcatch (Exception x)
、その後、あなたのポリシーに基づいて再スローするかどうかを決定するためにあなたを伝えます。遅すぎる - finally
ブロックは、すでにその時点で実行されています。それをしないでください。
あなたはおそらく、エンドユーザーがそれを見ることができるどこでもキャッチされない例外を望んでいないだろうが、あなたのAPIのクライアント(他のプログラマは)例外を処理する方法を決定できるようにすることが多い許容されます。
たとえば、あなたはJavaクラスライブラリを設計しているとします。あなたは文字列になりますpublicメソッドを公開します。あなたのアプリケーションでは、ヌル入力値は、エラーが発生します。代わりに、エラーを自分で処理するのではなく、IllegalArgumentExceptionをスローし、その後、NULL値をチェックするために許容可能である。
あなたは、もちろん、あなたの方法は、このような状況では、この例外をスローすることを文書化する必要があります。この動作は、あなたの方法の契約の一部になります。
これは、あなたが「巻き込まれ」によって何を意味するかに依存します。何か、どこかは最終的にそれが根底にあるOSまたは何か他のものあるかどうかの例外をキャッチします。
私たちは、個々のジョブで構成されるジョブ計画を実行したワークフローシステムを持っています。各ジョブには、コードのユニットを実行します。外部のワークフローシステムは、それをキャッチするような例外のいくつかのために、我々は(投げのプロセスの外に完全に起こった)コードでそれらを扱うが、スタックをそれをスローする必要はありません。
、そして、あなたの理由は、あなた自身です。私ははそれらのほとんどは非常に良い理由はいえないが、例外をスローし、アプリが死なせする場合がありますあなたがをいくつかの状況を考えることができます。
デバッグ時に最高の理由が通常です。私は頻繁に何かが失敗した場合、私がよく知っていることができるようにデバッグ中に例外を無効にします。デバッガを持つマシン上でそれを実行している場合にもちょうどデバッガでスローされた例外ブレークをオンにすることができます。
例外がスローされた後、別の可能な理由が継続されたときに意味がありませんまたは可能な回復不能なデータの破損またはより悪いことになる(レーザービームでロボットをと思いますが、あなたはIMOこれらの状況に気必ずごapplicaitonお得な情報でなければなりません、プログラムをクラッシュする)だけの怠惰な方法です。
あなたは、誰かがあなたの例外をキャッチしますならば、あなたは見当がつかない、APIコード、またはあなた自身を使用することはありませんFrameworkのコードを書いている場合。
は、うん、それはそれらを伝えるためにサービス/オブジェクトを消費した現像剤を平手打ちに私の唯一の機会だ「それは間違ってウルdO1nを!!!!」ます。
これとあなたが許可するか、一見「不可能」ですしていない可能性を取り除きます。すべての例外をキャッチし、混乱に囲まれただけの壁に囲まれた庭園です続けるアプリます。
ばいから緩やかなとする大規模システムが何らかの処理データだと思っている一貫した。
や
いつの間にか、を検出する、アプリケーションの状態となってい統一性がない。
や
システムんだノウハウの矛盾の回復を優雅に
そして、あり、例外をスローしながら、できる限り詳し、原因への応用金型、出来るだけ早い時期に回避だけ電源をオンにする"という更なる被害のデータです。れば復興できるという重要な悪化させ問題のようfeeblyに散らかっていたとします。
降線に沿ったり、チェーンのイベントに矛盾するものについて理解を深い高等施設のキャッチできることを除、修理の状態で、最小限の中断を余儀なくされた。
ライブラリーは、多くの場合、条件はそれがアプリケーションコードによって生じることが許されていないはず生じれば、防御的プログラミングのチェックに基づいて、例外がスローされます。アプリケーションコードは、多くの場合、これらの無効な条件のほとんどが発生することはありませんので、例外がスローされることはありませんので、それらをキャッチしない点がありませんよう書き込まれます。
キャッチされない例外の影響が実際にスローされる(私はほとんど違いが何であるかという明確なかなりのC#よりも、C ++の観点で考えると、いないよ)、言語によっては、おそらくで行われていたものと同じです例外は前の日に発明されました。 Cライブラリにおける防御プログラミングのための共通のポリシーは、例えば、エラーメッセージを表示して直ちにプログラムを終了することであった。
の違いは、例外スローが(うまくいけば、これはユニットテストで発見されます)が可能であることが判明した場合、より建設的な方法で問題から回復することができます例外ハンドラを追加するために、多くの場合、比較的容易であるということです。あなたは例外投げる呼び出しが行われる前の状態が発生することができないことを確認するためのライブラリを書き換え、またはアプリケーションコードで複雑なチェックを追加する必要はありません。
私はかなりの数の例外がキャッチされないことをスローしています。彼らは守備の目的のためにすべてであり、捕捉されなかったということは起こらない例外のために悪いですが、これは今まで私がこれまでにアプリケーションコードで考慮しなかったエラー条件のために、開発とテスト中に発生します。それが発生したときに修正が厄介であるために、それは珍しいです - 大規模なリファクタリングの必要は、アプリケーションコードの必要はエラー状態をチェックし、比較的単純な回復または「持つだけでcatch節を持つ大規模な複雑にしないように私はそれを行うことはできません怖い、デーブごめんなさい。」全アプリを失敗することなくます。