使用 Error、RuntimeException、Throwable 和 Exception 等通用異常可防止呼叫方法以不同於應用程式產生的錯誤的方式處理真正的、系統產生的例外。
滿天的星座2017-06-30 09:58:07
這個很容易理解啊.
打個簡單的比方. 現在做一個登錄有用戶不存在/密碼錯誤...
這些錯誤類型, 如果你直接使用RuntimeException
代碼要寫成這樣.
throw new RuntimeException("user not found"); // 用户不存在
throw new RuntimeException("password not match"); // 密码错误
捕捉異常
try {
// ...逻辑
} catch(RuntimeException e) {
if("user not found".equals(e.getMessage())) {
// ...逻辑
} else if("password not match".equals(e.getMessage())) {
// ...逻辑
}
}
反之自訂異常實作如下:
throw new UserNotFoundException("user not found"); // 用户不存在
throw new PasswordNotMatchException("password not match"); // 密码错误
捕捉異常
try {
// ...逻辑
} catch(UserNotFoundException e) {
// ...逻辑
} catch(PasswordNotMatchException e) {
// ...逻辑
}
透過message
判斷處理異常邏輯有很多弊端, 例如message
是動態的, 那將無法準確的處理.
當然我們也可以定義一個通用的異常類型, 通過業務碼去判斷會更加準確, 同時也會減少異常類型的定義, 減少程式碼的冗餘. 下面有一段kotlin
程式碼, 目前我是使用的這種處理方式.
interface BizCode {
val code: Int
val msg: String
}
enum class BizCodes(override val code: Int, override val msg: String): BizCode {
// ====================================================== //
// 公共错误码 0 - 999 //
// ====================================================== //
/**
* 未知错误.
*/
C_0(0, "未知错误"),
/**
* HTTP Request 参数错误.
*/
C_999(999, "HTTP Request 参数错误"),
// ====================================================== //
// client 错误码 1000 - 1999 //
// ====================================================== //
/**
* 未发现指定 client_id 客户端记录.
*/
C_1000(1000, "未发现指定 client_id 客户端记录"),
C_1001(1001, "client_secret 不匹配"),
// ====================================================== //
// user 错误码 2000 - 2999 //
// ====================================================== //
/**
* 未发现指定 email 的用户.
*/
C_2000(2000, "未发现指定 email 的用户"),
C_2011(2011, "password 不匹配"),
//
;
override fun toString(): String {
return "[$code] $msg"
}
}
class BizCodeException : RuntimeException {
val bizCode: BizCode
constructor(bizCode: BizCode) : super(bizCode.toString()) {
this.bizCode = bizCode
}
constructor(bizCode: BizCode, e: Exception) : super(bizCode.toString(), e) {
this.bizCode = bizCode
}
override fun fillInStackTrace() = this
}
怪我咯2017-06-30 09:58:07
Exception直接拋的話,Nginx 會把你定義message 覆蓋掉,導致看不到具體資訊。
建議的做法是,自己定義一個exception,去繼承 RuntimeException,這個就知道你的exception 是什麼,也方便找出問題。