简体   繁体   English

我应该抛出什么异常并应该提供消息?

[英]What exception should I throw and should I provide a message?

I have a situation where a user operation changes the current status of a request. 我遇到一种情况,其中用户操作会更改请求的当前状态。

Depending on the current status then only certain operations are possible ie 根据当前状态,只有某些操作是可能的,即

Pending can be Approved or Rejected or Cancelled Approved can be 'Cancel Requested' 'Cancel Requested' can be 'Cancellation Approved' or 'Cancellation Requested' 可以批准,拒绝或取消待处理可以是“已取消请求”,“已请求取消”可以是“已取消批准”或“已取消请求”

My question is what type of exception should I raise if the requested operation cannot be carried out? 我的问题是,如果无法执行请求的操作,我应该提出哪种异常? Should I use an inbuilt exception or should I create a custom exception such as InvalidCurrentStatusException or some such? 我应该使用内置异常还是应该创建自定义异常,例如InvalidCurrentStatusException或此类?

Looking at the documentation for InvalidOperationException seems a prime candidate as it is 'the exception that is thrown when a method call is invalid for the object's current state'. 查看InvalidOperationException的文档似乎是一个不错的选择,因为它是“方法调用对该对象的当前状态无效时引发的异常”。

If I go with the second option of a custom exception then I don't need to provide a message. 如果我选择了自定义异常的第二个选项,则无需提供消息。

If I use the inbuilt InvalidOperationException should I provide a message and what should that message be? 如果我使用内置的InvalidOperationException,我应该提供一条消息,该消息应该是什么?

UPDATE: 更新:

here's the code I have at the moment: 这是我目前的代码:

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();
}

You should never use an Exception (or any subclass) to control the state of the application, or indicate logical flow. 绝对不要使用Exception (或任何子类)来控制应用程序的状态或指示逻辑流。 Instead you should create a class that acts as a "result" in which you add a property that has the "status" -- as some others have already commented an enum is a prime example of a desirable use-case. 相反,您应该创建一个充当“结果”的类,在其中添加具有“状态”的属性-正如其他一些人已经评论过的,枚举是理想用例的主要示例。

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

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

Then simply pass around an instance of this object. 然后只需传递该对象的实例即可。

Custom exception would be the best option in this case. 在这种情况下,自定义例外将是最佳选择。 And you've guessed it right - there should be two types of those (as your comments suggest). 您猜对了,应该有两种类型(如您的评论所建议)。 The classes for those should be named to be self-describing: - InvalidApproverException - UnexpectedStatusException 这些类的名称应自描述:-InvalidApproverException-UnexpectedStatusException

Both can actually be derieved or even replaced by InvalidOperationException, but then you'll have to provide similar exception message every time. 实际上,两者都可以被InvalidOperationException删除,甚至可以替换为InvalidOperationException,但是您每次都必须提供类似的异常消息。 The good thing about custom exceptions is that you can add some more information about the context of the exception. 关于自定义异常的好处是您可以添加有关异常上下文的更多信息。 Specifically, the InvalidApproverException - can expose the actual approver's id, who for the operation has failed. 具体来说,InvalidApproverException-可以公开实际的批准者ID,该操作的失败者是谁。 This could be useful later down the road. 以后可能会很有用。 Also - it can internally set the message to some constant string: something similar to: "The caller is not the initiator of the request". 另外-它可以在内部将消息设置为某个常量字符串:类似于:“调用方不是请求的发起方”。 As or the second exception (UnexpectedStatusException) - I'd expose the CurrentRequestStatus property on it as well and again have a constant error message. 作为第二个异常(UnexpectedStatusException)-我也将公开CurrentRequestStatus属性,并再次出现一个恒定的错误消息。 That just simplifies the handling down the road. 这只是简化了以后的处理。 Here is a sample code for the exception: 这是该异常的示例代码:

public class UnexpectedStatusException : Exception { private const string DefaultExceptionMessage = "The request is not in an expected state."; “;公共类UnexpectedStatusException:异常{私有常量字符串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;
}

} }

public enum LeaveRequestStatus { // Request statueses here } 公共枚举LeaveRequestStatus {//在此处请求雕像}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM