【问题标题】:Handling Known Errors and Error Messages in a Method处理方法中的已知错误和错误消息
【发布时间】:2010-10-14 01:16:33
【问题描述】:

处理方法中发生的已知错误有哪些好方法?

我们以用户注册方式为例。当用户注册时,会调用方法SignUp( User user )。可能会发生一些已知错误。

  • 邮箱已注册
  • 用户名已注册

你可以抛出特定的异常:

public void SignUp( User user )
{
    // Email already exists
    throw new EmailExistsException();
}

现在可以捕获特定的异常。

在我看来这很糟糕,因为异常被用于流量控制。

如果成功,您可以返回一个布尔值,并传入一个错误消息,如果发生错误,该消息将被设置:

public bool SignUp( User user, out/ref string errorMessage )
{
    // Email already exists
    errorMessage = "Email already exists.";
    return false;
}

我不喜欢这个有几个原因。

  • 必须返回一个值。如果方法需要返回值怎么办?
  • 每次都必须传入错误消息。
  • 方法的使用者应该是决定消息是什么的人。

我们只说方法中设置的实际消息是错误的。

您可以使用错误代码:

public enum Errors
{
    Successful = 0,
    EmailExists,
    UsernameExists,
    Etc
}

public Errors SignUp( User user )
{
    // Email already exists
    return Errors.EmailExists;
}

// or

public void SignUp( User user, out/ref Errors error )
{
    // Email already exists
    error = Errors.EmailExists;
}

最后一个是我最喜欢的,但我还是不太喜欢。我不喜欢传入错误代码的想法。就此而言,我也不喜欢返回代码的想法。

我喜欢使用自定义异常的想法,因为它看起来更简洁一些,但我不喜欢使用异常进行流控制的想法。也许在像这个例子这样的特定情况下,系统中已经存在的电子邮件应该是一个例外,没关系。

其他人在这种情况下做了什么?

【问题讨论】:

标签: c# .net


【解决方案1】:

在这种情况下,我将创建一个名为 NewUserRegistrationException 的用户定义异常,其特殊属性(名为 Reason)将包含失败的原因

使用您的示例,枚举器

public enum RegistrationErrorType
{
    Successful = 0,
    EmailAlreadyExists,
    UsernameAlreadyExists,
    Etc
}

很好理解。

如果想通过调用您的方法注册新用户,只需 .ToString() 弹出一般错误的异常,或者(在阅读文档之后)switch Reason属性并做出相应的反应(关注电子邮件字段,将密码涂成红色等)。

示例代码:

public class NewUserRegistrationException : Exception
{
    public RegistrationErrorType Reason { get; private set; }
    public NewUserRegistrationException(RegistrationErrorType reason)
        : base()
    {
        Reason = reason;  
    }
    public NewUserRegistrationException(RegistrationErrorType reason, string message)
        : base(message)
    {
        Reason = reason;  //might as well create a custom message?
    }
    public NewUserRegistrationException(RegistrationErrorType reason, string message, Exception inner)
        : base(message, inner)
    {
        Reason = reason; //might as well create a custom message?
    }
}

【讨论】:

  • 我不喜欢使用异常进行流控制,但如果是错误,那就是错误。我想应该有办法提前检测。与 File.Open 一样,您将首先检查文件是否存在。 File.Open 应该仍然可能抛出 FileNotFound 异常或其他东西,如果它不存在。
【解决方案2】:

每当我开始考虑像这样的一个常见问题时,我做的第一件事就是检查是否有人已经提出了一个好的解决方案......所以当谷歌搜索“.net 验证框架”时,很多好结果弹出...

最近我一直在使用 TNValidate (http://tnvalidate.codeplex.com/)

【讨论】:

  • 我真的不认为这是验证。我想这个具体的例子,可以使用验证。我说的是一般的方法。
  • 我明白,但是请检查 tnvalidate 库的 Validator.cs 和 ValidatorResult.cs 类,这与您可以使用的已知错误完全相同的方法。我不认为在这里使用自定义异常是一个好的解决方案......
  • 那么,你认为这个类应该有一个可以检查的 HasErrors 方法/属性和某种带有错误列表的属性吗?
  • 由于 TNValidate 是开源的,我将扩展它以允许这样的语法:Validate.That(Email, "Email address").IsUnique();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多