2011-11-11 10 views
7

新しい例外タイプを導入するとき、私はいつもこれを正しく行う方法がわかりません。共通のコンベンションはありますか?どうやってやるの?例外に名前を付けて整理するにはどうすればよいですか?

私はこれも命名影響

(それらがに使用されているユニットに保管してください?コンポーネントレベルでのパッケージレベルのユニットをお持ちですか?アプリケーション?)あなたがそれらを整理スコープに興味を持っています。どれくらいの文脈を含めるのですか?それらを非常に具体的にする(EPersonIDNotFoundErrorのように)か、ENOTFoundErrorのように再利用可能にする方が良いですか?

「エラー」という接尾辞は何時に追加すればいいですか?私は論理を見ることができません。 Classes.pasに:

EWriteError = class(EFilerError); 
    EClassNotFound = class(EFilerError); 
    EResNotFound = class(Exception); 
+0

重大度とパッケージごとに例外を整理するとよいと思います。重大度別データ読み込み/保存エラーからの妥当性検査の例外を分離します。例外インスタンスには、発生した機会に関するより具体的な詳細が含まれています。 – too

+1

これは疑問ではありません...潜在的な議論(トローリング? IMHOこれはSOの目的にはうまく適合しません。 –

+0

@Arnaudさて、これに答えてみましょう。私は本当に入力を感謝しています。 –

答えて

6

私の知っている唯一の本当の慣例は、Eとそれらの接頭辞です。 私は過去にはそれほど多くの考えを与えていませんでしたが、今は考えてみましょう。ErrorExceptionの両方が後置符号としてよく使われているようです。それらを混ぜると、間違った入力に繋がっている間に、数字が間違っているのに対して、壊れた接続や読めないファイルのように、予期せず間違っているものに関連しているといいでしょう。誰かがテキストを入力しました。

対VCLがあまりにも特定の規則に従っているようだが、それはそれなしではっきりとエラーではないでしょう場合にのみ、接尾辞を追加しているようだ、例えば

EConvertError、EMathError、EVariantError

EAccessViolation、EInvalidPointer、EZeroDivide

後者は最初のリストは、特定のプロセスまたはエンティティのエラーを示すために、接尾辞が必要なエラー自体が、記載されています。

これらの例はSysUtilsにあります。多くの例外クラスだけでなく、さらに多くの例外のための基本クラスも含まれているので、ここで見てください。 EHeapExceptionやESafecallExceptionのような、まったく遭遇したくない非常に具体的なエラーを除いて、ほとんどはExceptionにあります。

+0

エラーメッセージ自体が障害状態をかなりうまく転送している場合、「エラー」をスキップするのに良い点。あなたは "例外"と "エラー"を混在させますか? –

+1

「エラー」はほとんどありませんが、私は今から考えていますが、この質問から私はそれについて考えていました。しかし、私は通常、多くの例外タイプを導入しません。私はいくつかの基本的なアプリケーションレベルの例外を作成する傾向があり、私は(再)既存の例外をたくさん使用します。私がいくつかの値を変換するのに失敗した場合、EConvertErrorを使ってうれしく思います。私自身のリスト/配列/コレクションの実装では、EListIndexErrorを呼び出せば簡単に再利用できます。私は確かに見つけることができない各フィールドのために別々の例外を作成していません。 – GolezTrol

1

新しい例外を作成するときは、アプリケーション全体を作成します。私は最も詳細なエラーからクラス(Exception)のような最も一般的なものに始まり、それに応じて名前を付けます。

この例では、EPersonIDNotFoundError、ENotFoundError、Exceptionを使用します。あなたは(Exception.Createに逃げることができる簡単なアプリケーションのための通常

それは本当にあなたがあなたのエラーメッセージと何(あなたがエラーのログを保持する場合)、あなたのログに含めるから望むどのくらい詳細に依存

1

'エラーメッセージ')。例外が強力になるところでは、クラスを見ることによって必要とされる応答の種類を検出することができます。 DelphiはすでにEAbortを呼び出すAbortプロシージャによってこれを行います。 EAbortは 'エラー'を起こさないという点で '特別な'ものです。つまり、一種の「サイレント」例外です。このクラス固有のアクションを使用して、例外を調べてさまざまなことを行うことができます。 EMyWarning、EMyVeryNastyErrorなどを作成することができます。これらはそれぞれ、基本的なExceptionタイプの子孫です。

さらに、新しい例外クラスを定義して、例外がトラップされたポイントまでさらに情報を伝達することができます。コード(チェックしない)と例えば:

EMyException = class(Exception) 
    constructor Create(const AErrorMessage : string; AErrorCode : integer); reintroduce; 
PUBLIC 
    ErrorCode : integer 
end; 

constructor EMyException.Create(const AErrorMessage : string; AErrorCode : integer); 
begin 
    inherited Create(AErrorMessage); 
    ErrorCode := AErrorCode; 
end; 

あなたは今、あなたは例外を発生し、例外がキャッチされたとき、あなたはそれが利用可能なとき「のErrorCode」を設定する可能性があります。例外はかなり強力です。

+0

質問への答えは実際にはありませんが、最初は例外から継承する理由の良いデモンストレーションです。そして私はEAbortが大好きです。 :)あなたは非常に多くのことを中止することができます。例えば、OnBeforePostでEAbortを発生させ、そのような中断の多くを記録してレコードをポストすることを中止します。私はまた、複雑な操作を中止するために多くを使用します。 – GolezTrol

1

どの範囲でそれらを整理できますか?

最も一般的な例外に適合しようとするアプリケーション全体で、1つのユニットを使用します。他のすべては、例外がスローされるユニットに入ります。これらの例外が他のユニットで必要な場合は、作業中のサブシステムが使用する共通のユニットにそれらを移動します。

名前はどうですか?

ENotFoundErrorのような1つまたは2つのレベルの「一般的な」例外を作成してください。これらをアプリケーションのグローバルファイルに入れます。後で何が起こるのかわからないので、すべてを変更する必要があるため、一般化するのが難しいです。グローバルレベルのものを継承するユニットレベルの特別な例外を作成します。

「エラー」ポストフィックスはどうですか?

それについて考えるのをやめてください。 Add it.馬鹿だと思わない限り。

+2

コードがインターフェイスをたくさん使用する場合は、インターフェイスを宣言するユニットで例外を宣言しますが、実装するコードでは – mjn

+1

@mjnをスローしません。それ以外の場合、インタフェースのユーザは、実装者に依存することなく、例外クラスに対して特定のチェックを行うことはできません。 –

関連する問題