WCF は例外を握りつぶしてしまう
WCF サービス内で発生した例外は、何もしなければ握り潰されます。そして、代わりに FaultException がクライアントに返されます。
例外の内容も、「例外がハンドルされなかった」という旨に変更されてしまいます。これじゃ何が原因なのか、全く分からないですよね。
クライアントに役立つ情報を返したいなら、自分で FaultException をスローしよう
クライアント側に役立つ情報を返したい場合は、一度例外をキャッチし、自分で FaultException に置き変える必要があります。
public class FooService : IFooService { public void Foo() { try { // アプリケーションロジックで例外発生 throw new ArgumentException("エラー発生"); } catch (ArgumentException ex) { // 例外をキャッチし、FaultException に置き変える throw new FaultException("エラーの説明"); } } }
ジェネリックな FaultException クラスも使える
ジェネリック版である FaultException
まずエラー情報を格納するクラスを用意。クライアント〜サービス間で受け渡すので、DataContract を付ける必要があります。
[DataContract] public class ErrorInfo { [DataMember] public string Message { get;set; } }
このクラスにエラー情報を詰め、FaultException
public class FooService : IFooService { public void Foo() { try { // アプリケーションロジックで例外発生 throw new ArgumentException("エラー発生"); } catch (ArgumentException ex) { // 例外をキャッチし、FaultException でラップして // 再スローしてみる throw new FaultException<ErrorInfo>( new ErrorInfo() { Message = "エラーの詳細" }, new FaultReason("エラーの説明")); } } }
FaultException
[ServiceContract] public interface IFooService { [OperationContract] [FaultContract(typeof(ErrorInfo))] void Foo(); }
これで、クライアント側に FaultException
例外クラスを FaultException に渡したらダメ
面倒くさがって、Exception 派生クラスをそのまま FaultException
この辺りは、プロジェクトでちゃんと例外処理の方針を決めておかないといけませんね。