使用 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
是动态的, 那将无法准确的处理.message
判断处理异常逻辑有很多弊端, 比如message
是动态的, 那将无法准确的处理.
当然我们也可以定义一个通用的异常类型, 通过业务码去判断会更加准确, 同时也会减少异常类型的定义, 减少代码的冗余. 下面有一段kotlin
当然我们也可以定义一个通用的异常类型, 通过业务码去判断会更加准确, 同时也会减少异常类型的定义, 减少代码的冗余. 下面有一段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 是什么,也方便查找问题。