2016-03-26 9 views
0

У меня возникла ситуация, когда пользовательская операция меняет текущий статус запроса.Какое исключение я должен бросить, и должен ли я предоставить сообщение?

В зависимости от текущего состояния, то только определенные операции возможны т.е.

В ожидании могут быть утверждены или отклонены или Отменено Одобрено может быть «Отменить Запрошенный» «Отмена Запрошенный» может быть «Отмена Одобрено» или «Отмена Запрошено '

Вопрос: какой тип исключения я должен поднять, если запрошенная операция не может быть выполнена? Должен ли я использовать встроенное исключение или я должен создать настраиваемое исключение, такое как InvalidCurrentStatusException или некоторые такие?

Рассмотрение документации для InvalidOperationException кажется простым кандидатом, поскольку это «исключение, которое вызывается, когда вызов метода недействителен для текущего состояния объекта».

Если я перехожу со вторым вариантом специального исключения, то мне не нужно предоставлять сообщение.

Если я использую встроенное 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

Если вы можете обнаружить, что запрос недействителен, зачем вообще исключать какое-либо исключение из-за какого-либо сообщения об ошибке. Или лучше отключить недействительные параметры условно, чтобы пользователь не мог Do Bad Things. – 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

Специальное исключение было бы лучшим вариантом в этом случае. И вы догадались, что это правильно - должно быть два типа этих (как предполагают ваши комментарии). классы для тех, кто должен быть назван, чтобы быть самоописываемыми: - InvalidApproverException - UnexpectedStatusException

И на самом деле может быть derieved или даже заменить на InvalidOperationException, но тогда вы должны будете предоставить подобное сообщение Exception каждый раз. Хорошая вещь о пользовательских исключениях заключается в том, что вы можете добавить дополнительную информацию о контексте исключения. В частности, InvalidApproverException - может выставить фактический идентификатор assertver, который для операции потерпел неудачу. Это может быть полезно позже по дороге. Кроме того, он может внутренне настроить сообщение на некоторую константную строку: что-то похожее на: «Вызывающий не является инициатором запроса». Как или второе исключение (UnexpectedStatusException) - я бы также выставил на него свойство CurrentRequestStatus и снова получил постоянное сообщение об ошибке. Это просто упрощает обработку по дороге. Вот пример кода, за исключением:

класс UnexpectedStatusException общественности: Исключение { частное Const строка 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 здесь }

Смежные вопросы