Java 异常富集是一种可行的模式吗?

Java 异常富集是一种可行的模式吗?,java,error-handling,Java,Error Handling,我最近看到了Jakob Jenkov的一篇关于可充实异常的文章。我真的很喜欢这个主意 我已经做了4年的Java开发人员,但我仍然对如何处理第三方库抛出的所有SQLExcepion、IOException和随机异常感到非常恼火。最后,我花了很多心思考虑什么时候重新引用异常,或者将其包装为自定义异常,但是如果我编写自定义异常,那么我应该将其放入什么位置?与我正在编写的类在同一个包中,还是在一个中央“异常”包中?我甚至玩弄过将自定义异常声明为内部类,因为它们通常看起来是一次性的 无论如何,Jenkov

我最近看到了Jakob Jenkov的一篇关于可充实异常的文章。我真的很喜欢这个主意

我已经做了4年的Java开发人员,但我仍然对如何处理第三方库抛出的所有SQLExcepion、IOException和随机异常感到非常恼火。最后,我花了很多心思考虑什么时候重新引用异常,或者将其包装为自定义异常,但是如果我编写自定义异常,那么我应该将其放入什么位置?与我正在编写的类在同一个包中,还是在一个中央“异常”包中?我甚至玩弄过将自定义异常声明为内部类,因为它们通常看起来是一次性的

无论如何,Jenkov的想法如下:

在他概述的时候使用一个可充实的例外对我来说非常有吸引力,因为它似乎很容易避开我的大部分挫折。但我想我从来没有在我使用过的任何图书馆中看到过它。这有什么原因吗?这种方法是否存在我遗漏的一个主要缺陷

简单总结:

public class AppException extends Exception{
    public AppException(String errCode, String context, String userMessage, Throwable t){}

    public AppException(String, errCode, String context, String userMessage) {}

    public void addInfo(String errCode, String context, String userMessage){}
}

public class MyApp {
    public static void main(String [] args) {
        MyApp app = new MyApp();

            app.start(args[0], args[1]);        
    }

    public void start(String username, String password) {
        try {
            User user = loginController.login(username, password);
        } catch (AppException e) {
            if (e.getCode().contains("INCORRECT_PASSWORD")) {
                logger.warn(e.toString(), e);
                // Prompt user for new password and try again.
            } else {
                logger.error(e.toString(), e);
            }
        } catch (Exception e) {
            logger.error("Unexpected Exception.", e);
        }
    }
}

public class LoginController {
    public User login(String username, String password) {
        try {
            if (userDao.checkPassword(username, password)) {
                // Build and return the user object.
            }
        } catch (AppExcption e) {
            e.addInfo("LOGIN_FAILED", "LoginController", "Failed to login");
            throw e;
        }
    }
}

public class UserDao {
    public boolean checkPassword(String username, String password) {
        try {
            // Check the password against the DB.

            if (passwordIsCorrect) {
                return true;
            } else {
                throw new AppException("INCORRECT_PASSWORD", "UserDao", "Password for user " + username + " is not correct.");
            }
        } catch (SQLException e) {
            throw new AppException("DB_CONNECTION_ERR", "UserDao", "Can't connect to Database", e);
        }
    }
}
Jenkov的文章中提供了exception类的实际实现。在上面的代码示例中,如果无法访问数据库,则错误日志如下所示:

[LOGIN_FAILED, LogginController], [DB_CONNECTION_ERR, UserDao]
[LOGIN_FAILED, LogginController]: Failed to login
[DB_CONNECTION_ERR, UserDao]: Can't connect to Database
<<SQLException stacktrace here>>
我可能会为错误代码添加一个枚举或其他东西,以使选择性处理更容易,并确保它们实际上是唯一的。但是,错误消息提供了一个非常清晰、简洁的视图,可以很容易地添加额外的信息,因为错误会影响调用堆栈,以便开发人员能够重新创建错误


重复我的问题。为什么不更广泛地使用它?这种方法是否存在我所遗漏的一个主要缺陷?

自己研究一下,我不相信任何人都能客观地回答这个问题,因此每个答案都只是一个意见,这不是一个好的技术问题。
[LOGIN_FAILED, LogginController], [INCORRECT_PASSWORD, UserDao]
[LOGIN_FAILED, LogginController]: Failed to login
[DB_CONNECTION_ERR, UserDao]: Password for user [passed in username] is not correct.