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

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

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


当前回答

异常用于异常行为、错误、失败等事件。功能行为、用户错误等应该由程序逻辑来处理。由于错误的帐户或密码是登录例程中逻辑流的一部分,因此它应该能够毫无例外地处理这些情况。

其他回答

我想说,基本上每一个原教旨主义都会导致地狱。

您当然不希望以异常驱动流结束,但是完全避免异常也是一个坏主意。你必须在两种方法之间找到平衡。我不会为每种异常情况创建异常类型。这是没有成效的。

我通常更喜欢创建两种基本类型的异常,它们在整个系统中使用:LogicalException和TechnicalException。如果需要,可以通过子类型进一步区分这些类型,但通常不是没有必要。

技术异常指的是真正意想不到的异常,比如数据库服务器宕机,到web服务的连接抛出IOException等等。

另一方面,逻辑异常用于将不太严重的错误情况传播到上层(通常是一些验证结果)。

请注意,即使是逻辑异常也不是为了定期使用来控制程序流,而是为了突出显示流何时应该真正结束的情况。在Java中使用时,这两种异常类型都是RuntimeException子类,错误处理是高度面向方面的。

因此,在登录示例中,创建类似AuthenticationException的东西并通过枚举值(如UsernameNotExisting、PasswordMismatch等)来区分具体情况可能是明智的。这样就不会产生巨大的异常层次结构,并且可以将捕获块保持在可维护的级别。您还可以轻松地使用一些通用的异常处理机制,因为您已经对异常进行了分类,并且非常清楚要向用户传播什么以及如何传播。

我们的典型用法是,当用户输入无效时,在Web服务调用期间抛出LogicalException。异常被编组到SOAPFault详细信息,然后在客户机上再次被解组到异常,这将导致在某个web页面输入字段上显示验证错误,因为异常已正确映射到该字段。

这当然不是唯一的情况:您不需要点击web服务来抛出异常。你可以在任何特殊情况下自由地这样做(比如在你需要快速失败的情况下)——这都取决于你的判断。

首先,如果API的用户对特定的、细粒度的故障不感兴趣,那么为他们设置特定的异常就没有任何价值。

由于通常不可能知道什么可能对用户有用,一个更好的方法是有特定的异常,但确保它们继承自一个公共类(例如,std::exception或其在c++中的派生类)。这允许您的客户端捕获特定的异常(如果他们愿意的话),或者捕获更一般的异常(如果他们不关心的话)。

异常是一种代价高昂的效果,例如,如果您有一个用户提供了无效的密码,那么通常更好的方法是返回一个失败标志,或其他一些无效的指示。

这是由于异常处理的方式,真正的错误输入和唯一的关键停止项应该是异常,而不是失败的登录信息。

我有三种情况。

Bad or missing input should not be an exception. Use both client side js and server side regex to detect, set attributes and forward back to the same page with messages. The AppException. This is usually an exception that you detect and throw with in your code. In other words these are ones you expect (the file does not exist). Log it, set the message, and forward back to the general error page. This page usually has a bit of info about what happened. The unexpected Exception. These are the ones you don't know about. Log it with details and forward them to a general error page.

希望这能有所帮助

You may use a little bit generic exceptions for that conditions. For e.g. ArgumentException is meant to be used when anything goes wrong with the parameters to a method (with the exception of ArgumentNullException). Generally you would not need exceptions like LessThanZeroException, NotPrimeNumberException etc. Think of the user of your method. The number of the conditions that she will want to handle specifically is equal to the number of the type of the exceptions that your method needs to throw. This way, you can determine how detailed exceptions you will have.

顺便说一下,总是尝试为库的用户提供一些避免异常的方法。TryParse就是一个很好的例子,它的存在使你不必使用int。解析并捕获异常。在您的情况下,您可能希望提供一些方法来检查用户名是否有效或密码是否正确,这样您的用户(或您)就不必进行大量异常处理。这将有望产生更易于阅读的代码和更好的性能。