84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
使用 Error、RuntimeException、Throwable 和 Exception 等通用异常可防止调用方法以不同于应用程序生成的错误的方式处理真正的系统生成的异常。
这个很容易理解啊.打个简单的比方. 现在做一个登录有用户不存在/密码错误... 这些错误类型, 如果你直接使用RuntimeException 代码要写成这样.
用户不存在/密码错误...
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代码, 目前我是使用的这种处理方式.
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 }
说明的挺清楚了啊,方便捕获处理
Exception名字要有意义,RuntimeException名字没有意义
Exception直接抛的话,Nginx 会把你定义message 覆盖掉,导致看不到具体信息。建议的做法是,自己定义一个exception,去继承 RuntimeException,这个就知道你的exception 是什么,也方便查找问题。
运行时异常不需要捕获
这个很容易理解啊.
打个简单的比方. 现在做一个登录有
用户不存在/密码错误...
这些错误类型, 如果你直接使用RuntimeException
代码要写成这样.捕捉异常
反之自定义异常实现如下:
捕捉异常
通过
message
判断处理异常逻辑有很多弊端, 比如message
是动态的, 那将无法准确的处理.message
判断处理异常逻辑有很多弊端, 比如message
是动态的, 那将无法准确的处理.当然我们也可以定义一个通用的异常类型, 通过业务码去判断会更加准确, 同时也会减少异常类型的定义, 减少代码的冗余. 下面有一段
kotlin
当然我们也可以定义一个通用的异常类型, 通过业务码去判断会更加准确, 同时也会减少异常类型的定义, 减少代码的冗余. 下面有一段kotlin
代码, 目前我是使用的这种处理方式.说明的挺清楚了啊,方便捕获处理
Exception名字要有意义,RuntimeException名字没有意义
Exception直接抛的话,Nginx 会把你定义message 覆盖掉,导致看不到具体信息。
建议的做法是,自己定义一个exception,去继承 RuntimeException,这个就知道你的exception 是什么,也方便查找问题。
运行时异常不需要捕获