カスタム例外によるプログラムフロー

XMLファイルを解析しているプロセスがあります。

これはPAckageクラスで発生しています。

Packageクラスには、オブジェクトを無効な状態に設定するDelegateがあり、Packageクラスが発生したエラーの詳細情報が取得されます

簡単にするために、私はパッケージに渡されるfilitemを示しています。

すなわち、

foreach( var package in Packages)
{
try
{

    package.ProcessXml(fileitem.nextfile);

}
catch (CustomeErrorException ex)
{
    Logger.LogError(ex)
}
}

パッケージの中で私の検証は次のようになります

var Album = xml.Descendants()
    .Select(albumShards => new Album {
      Label = (string)albumShards.Descendants(TempAlbum.LabelLoc).FirstOrDefault() == "" ?
FailPackage("Error on label Load",Componets.Package,SubComp.BuildAlbum ) :  (string)albumShards.Descendants(TempAlbum.LabelLoc).FirstOrDefault()

この検証では、ラベルに ""が返されているかどうかをチェックします。そうであれば、エラー情報でコール失敗パッケージを呼び出して例外を作成します

 protected override void FailPackage(string msg, LogItem logItem)
         {
             Valid = ProcessState.Bad;
             Logger.LogError(msg,logItem);
             throw CustomErrorException(msg, Logitem);

         }

含まれているtry catchブロックを介してキャプチャされます

私の懸念は、プログラムフローの例外を使用しているということです。この問題に近づくにはどうすればよいのでしょうか、これは有効なパターンです。

2
ラベルはどれくらいの頻度で空ですか?
追加された 著者 Amy,
それは...エラーの時だけであってはならない
追加された 著者 HoopSnake,

2 答え

ProcessXmlは、特定のケースでその名前が暗示していることを実行できません。これらはエラーの場合です。名前の意味にかかわらず、例外はエラー処理のためのものです。

例外に関する最大の誤解の1つは、   "例外的な条件"のためのものです。現実は、彼らが   エラー状態を通知します。

Krzysztof Cwalina、フレームワーク設計ガイドライン:再利用可能な規約、慣用句、パターン。 NETライブラリ

言い換えれば、あなたは正しいです。 :)

上の本の例外に関する章で、いくつかの優れたガイドラインを読んでください。

2
追加された
私は時々 "例外的な条件"対 "エラー"の意味が少しすぎると思う。 「例外条件」という用語を使用する人は、例外を投げずに簡単かつ迅速に処理できる一般的なエラー発生のたびに例外を使用することに注意するだけです。たとえば、ユーザーの入力がゼロ除算を引き起こさないように例外に頼るのではなく、ユーザーにプロンプ​​トを出します。
追加された 著者 Andrew Barber,
@AndrewBarber - 公正なポイント。これは本書にも記載されています。 :)
追加された 著者 TrueWill,

エラーをProcessStateと共に置くことができます:

foreach( var package in Packages)
{
    package.ProcessXml(fileitem.nextfile);
    if(!package.Valid)
        Logger.LogError(package.Error)
}



var albumShards = xml.Descendants().FirstOrDefault();
if((string)albumShards.Descendants(TempAlbum.LabelLoc).FirstOrDefault() == "")
    return FailPackage("Error on label Load",Componets.Package,SubComp.BuildAlbum );

album = (string)albumShards.Descendants(TempAlbum.LabelLoc);


 protected override void FailPackage(string msg, LogItem logItem)
 {
     Valid = ProcessState.Bad;
     Logger.LogError(msg,logItem);
     Error = msg;
 }
0
追加された
また、すでにFailPackageメソッドにログインしています。他のロギングを追加して、その例外をスローしないで静かに失敗することもできます。
追加された 著者 ivowiblo,