2016-03-26 17 views
0

私は、ユーザー操作によってリクエストの現在のステータスが変更される状況があります。私は何の例外を投げるべきですか?私はメッセージを提供すべきですか?

のみ特定の操作が可能であり、現在の状況に応じて、すなわち

保留 が承認承認または却下または取り消すことができることが「キャンセル要求」することができます 「キャンセル要求」は「キャンセル「を取り消し承認済み」またはすることができます要求された '

私の質問は、要求された操作を実行できない場合にどのような例外を発生させるべきですか? inbuilt例外を使うべきですか、InvalidCurrentStatusExceptionやそのようなものなどのカスタム例外を作成する必要がありますか?

InvalidOperationExceptionのドキュメントを見ると、「オブジェクトの現在の状態に対してメソッド呼び出しが無効な場合にスローされる例外」のようにプライム候補に思えます。

カスタム例外の2番目のオプションを使用すると、メッセージを提供する必要はありません。

Inbuilt InvalidOperationExceptionを使用してメッセージを提供する必要がありますが、そのメッセージはどうすればよいですか?

UPDATE:

ここで、現時点で私が持っているコードです:

internal void CancelRequest(int requestID, int userID, string notes) 
{ 

     DateTime editDate = DateTime.UtcNow; 

     var request = this.FindByID(requestID, CancelRequestIncludes); 

     if(request == null) 
     { 
      throw new ArgumentException(InvalidRequestMessage); 
     } 

     var currentStatus = request.LeaveRequestStatuses.Where(s => s.IsCurrent).FirstOrDefault(); 

     if (currentStatus.StatusID == (int)RequestStatuses.RequestPending) 
     { 
      SetNewRequestStatus(request, currentStatus, RequestStatuses.CancellationApproved, userID, notes, editDate); 
     } 
     else if (currentStatus.StatusID == (int)RequestStatuses.RequestApproved) 
     { 
      if (ValidApprover(request.UserID, userID)) 
      { 
       SetNewRequestStatus(request, currentStatus, RequestStatuses.CancellationPending, userID, notes, editDate); 
      } 
      else 
      { 
       //throw an invalid approver exceptioon 

      } 
     } 
     else 
     { 
      //throw exception as cant carry out cancellation 
     } 

     Context.SaveChanges(); 
} 
+0

私はシステムクラスのための私のコードとシステム例外のためのカスタム例外を使用することを好むこれはあなたを助けることができます。 – ganchito55

+1

要求が無効であることを検出できる場合は、何らかのエラーメッセージと比較して例外をスローするか、無効なオプションを条件付きで無効にしてユーザーが傾けることはできません悪いことをする。 – Plutonix

+0

私は@Plutonixに同意します。この場合、例外をスローするのではなく、一種の「アプリケーションステータス」プロパティと列挙型(承認済み、拒否済み、キャンセル済み)を使用できます。あなたはプログラムフロー制御の例外やコードが検出できる状況に対して例外を使用しないでください。 –

答えて

4

あなたは、アプリケーションの状態を制御するためにException(または任意のサブクラス)を使用しない、または論理的な流れを示しありません。その代わりに、 "状態"を持つプロパティを追加する "結果"として機能するクラスを作成する必要があります。他の人が既に列挙したものは望ましいユースケースの主要な例です。

public enum RequestStatus 
{ 
    Approved, 
    Rejected, 
    Cancelled, 
    UnableToCarryOut 
} 

public class RequestResult 
{ 
    public RequestStatus Status { get; set; } 
    public string Message { get; set; } 
} 

このオブジェクトのインスタンスを渡します。

+0

これは私が通常行うことですが、最近読んだことや読んだことの多くは例外を使うべきであることを暗示しているようです。 –

+1

私はあなたが読んでいるものが不思議です。私はまだそれが本当に例外的でない限り、あなたが投げるべきではないと考えています。 –

+0

私はこのhttp://codeutopia.net/blog/2010/03/11/should-a-failed-function-return-a-value-or-throw-an-exception/を読んでいました。 (と私の通常の)戻り値のコードを使用する方法: 'しばしば忘れられた事実はアプリケーションの安定性です。できるだけ安定したクリティカルなコードを書いているなら、何を使うべきですか?戻り値。 ' –

0

この場合、カスタム例外が最適です。そしてあなたはそれを正しく推測しました - あなたのコメントが示唆するように、それらの2つのタイプがあるべきです。それらのため のクラスは自己記述であることを命名する必要があります。 - InvalidApproverException - UnexpectedStatusException

の両方が実際にderievedすることができ、さらにはInvalidOperationExceptionが置き換えられますが、その後は同様の例外メッセージを毎回提供する必要があります。カスタム例外の良い点は、例外のコンテキストに関する情報を追加できることです。具体的には、InvalidApproverException - 実際の承認者のID(操作の失敗者)が公開される可能性があります。これは後で道路に役立つ可能性があります。また、内部的にメッセージをいくつかの定数文字列に設定することができます: "呼び出し元は要求の開始側ではありません"。 または2番目の例外(UnexpectedStatusException) - 私はCurrentRequestStatusプロパティを同様に公開し、一定のエラーメッセージを再度表示します。それは道路の処理を単純化します。

パブリッククラスUnexpectedStatusException:例外 { private const string DefaultExceptionMessage = "要求が予期された状態ではありません。「;

public LeaveRequestStatus CurrentStatus 
{ 
    get; private set; 
} 

public UnexpectedStatusException(LeaveRequestStatus currentStatus) : this(currentStatus, DefaultExceptionMessage) 
{ 
} 

public UnexpectedStatusException(LeaveRequestStatus currentStatus, string message) : base(message) 
{ 
    this.CurrentStatus = currentStatus; 
} 

}

パブリック列挙LeaveRequestStatus { //リクエストはこちら をstatueses}

関連する問題