Die Verwendung allgemeiner Ausnahmen wie Error, RuntimeException, Throwable und Exception verhindert, dass aufrufende Methoden echte, vom System generierte Ausnahmen anders behandeln als von der Anwendung generierte Fehler.
public void foo(String bar) throws Throwable { // Noncompliant
throw new RuntimeException("My Message"); // Noncompliant
}
public void foo(String bar) {
throw new MyOwnRuntimeException("My Message");
}
這個很容易理解啊.
打個簡單的比方. 現(xiàn)在做一個登錄有用戶不存在/密碼錯誤...
這些錯誤類型, 如果你直接使用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())) {
// ...邏輯
}
}
反之自定義異常實現(xiàn)如下:
throw new UserNotFoundException("user not found"); // 用戶不存在
throw new PasswordNotMatchException("password not match"); // 密碼錯誤
捕捉異常
try {
// ...邏輯
} catch(UserNotFoundException e) {
// ...邏輯
} catch(PasswordNotMatchException e) {
// ...邏輯
}
通過message
判斷處理異常邏輯有很多弊端, 比如message
是動態(tài)的, 那將無法準確的處理.
當(dāng)然我們也可以定義一個通用的異常類型, 通過業(yè)務(wù)碼去判斷會更加準確, 同時也會減少異常類型的定義, 減少代碼的冗余. 下面有一段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 參數(shù)錯誤.
*/
C_999(999, "HTTP Request 參數(shù)錯誤"),
// ====================================================== //
// client 錯誤碼 1000 - 1999 //
// ====================================================== //
/**
* 未發(fā)現(xiàn)指定 client_id 客戶端記錄.
*/
C_1000(1000, "未發(fā)現(xiàn)指定 client_id 客戶端記錄"),
C_1001(1001, "client_secret 不匹配"),
// ====================================================== //
// user 錯誤碼 2000 - 2999 //
// ====================================================== //
/**
* 未發(fā)現(xiàn)指定 email 的用戶.
*/
C_2000(2000, "未發(fā)現(xiàn)指定 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
}
Exception直接拋的話,Nginx 會把你定義message 覆蓋掉,導(dǎo)致看不到具體信息。
建議的做法是,自己定義一個exception,去繼承 RuntimeException,這個就知道你的exception 是什么,也方便查找問題。