gri*_*gon 7 java error-handling
我最近看到 Jakob Jenkov 写的一篇关于丰富异常的文章。我真的很喜欢这个主意!
我已经成为一名 Java 开发人员 4 年了,但我仍然对试图弄清楚如何处理第三方库抛出的所有 SQLExcepions、IOException 和随机异常感到非常恼火。我最终花了很多心思思考何时合适重新抛出异常,或者将其包装为自定义异常,但如果我编写自定义异常,那么我应该放置它吗?与我正在编写的类在同一个包中,还是在中央“例外”包中?我什至尝试过将自定义异常声明为内部类,因为它们通常看起来非常一次性。
无论如何,Jenkov 的想法概述如下: http: //tutorials.jenkov.com/java-exception-handling/exception-enrichment.html
正如他所概述的那样,使用一个可丰富的例外似乎对我来说非常有吸引力,因为它似乎可以轻松地回避我的大部分挫败感。但我认为我从未见过它在我使用过的任何库中使用过。这是有原因的吗?我所遗漏的这种方法是否存在重大缺陷?
简单总结:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jenkov 的文章中提供了异常类的实际实现。在上面的代码示例中,如果数据库无法访问,错误日志将如下所示:
[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>>
Run Code Online (Sandbox Code Playgroud)
但如果输入了错误的密码,则会出现:
[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.
Run Code Online (Sandbox Code Playgroud)
我可能会为错误代码添加一个枚举或其他内容,以使选择性处理更容易,并确保它们实际上是唯一的。但是错误消息给出了错误时的非常清晰简洁的视图,并且很容易在错误出现在调用堆栈中时添加附加信息,以便开发人员能够重新创建错误。
所以重复我的问题。为什么这种方法没有得到更广泛的应用?我所遗漏的这种方法是否存在重大缺陷?
| 归档时间: |
|
| 查看次数: |
736 次 |
| 最近记录: |