我为我的应用程序不期望的每个条件创建了异常。UserNameNotValidException, PasswordNotCorrectException等。

然而,我被告知我不应该为这些条件创造例外。在我的UML中,那些是主要流程的异常,那么为什么它不应该是异常呢?

是否有创建异常的指导或最佳实践?


当前回答

安全性与您的示例混为一谈:您不应该告诉攻击者用户名存在,但密码是错误的。这是你不需要分享的额外信息。只要说“用户名或密码不正确”。

其他回答

避免抛出异常的主要原因是抛出异常涉及大量开销。

下面这篇文章指出的一件事是,例外是针对异常条件和错误的。

错误的用户名不一定是程序错误,而是用户错误……

下面是关于。net中的异常的一个不错的起点: http://msdn.microsoft.com/en-us/library/ms229030 (VS.80) . aspx

以下是我的建议:

我不认为这总是一个抛出异常的好方法,因为它将花费更多的时间和内存来处理这样的异常。

在我看来,如果某些事情可以用“友好、礼貌”的方式处理(这意味着如果我们可以“通过使用if......或类似的东西来预测这样的错误),我们应该避免使用“异常”,而只是返回一个像“false”这样的标志,用一个外部参数值告诉他/她详细的原因。

举个例子,我们可以这样创建一个类:

public class ValueReturnWithInfo<T>
{
   public T Value{get;private set;}
   public string errorMsg{get;private set;}
   public ValueReturnWithInfo(T value,string errmsg)
   {
      Value = value;
      errMsg = errmsg;
   }
}

我们可以使用这种“多值返回”类来代替错误,这似乎是处理异常问题的一种更好、更礼貌的方式。

但是,请注意,如果一些错误不能如此容易地用"if"......(例如FileIO异常)描述(这取决于您的编程经验),则必须抛出异常。

一个经验法则是在您通常无法预测的情况下使用异常。例如数据库连接、磁盘上丢失的文件等。对于您可以预测的场景,例如用户试图使用错误的密码登录,您应该使用返回布尔值的函数,并知道如何优雅地处理这种情况。您不希望仅仅因为有人输入了密码错误而抛出异常,从而突然结束执行。

主要有两类异常:

1)系统异常(如数据库连接丢失)或 2)用户异常。(例如用户输入验证,“密码不正确”)

我发现创建自己的用户异常类很有帮助,当我想抛出一个用户错误时,我想要以不同的方式处理(即资源错误显示给用户),然后我在我的主错误处理程序中所需要做的就是检查对象类型:

            If TypeName(ex) = "UserException" Then
               Display(ex.message)
            Else
               DisplayError("An unexpected error has occured, contact your help  desk")                   
               LogError(ex)
            End If

我同意japollock的说法当你不确定手术的结果时就放弃接受。调用api、访问文件系统、数据库调用等。任何时候你都要超越编程语言的“界限”。

我想补充一点,请随意抛出一个标准异常。除非你打算做一些“不同”的事情(忽略,电子邮件,日志,显示twitter鲸鱼图片之类的东西),否则不要费心自定义异常。