今天实在想写完这篇再睡,最近总结了几个关于异常的点,关于在实战项目中的使用(小型系统),个人的一些观点,如果有哪里不太完善的欢迎大家来评论。
在写一些业务逻代码的时候我们总是要根据不同的业务情况来抛出不同的错误提示给用户,总不能蠢到一律都是系统异常对吧。。。这样用户看不懂自己也不知道哪里有问题。
举一个简单的小例子(通俗易懂)。
假如我们要实现一个系统注册用户的场景(身份证号,手机号不能重复),前端在调用后端保存方法的时候在后端需要做手机号、身份证号的判重。假如身份证号重复,需要抛出指定的错误码0001;假如手机号重复,需要抛出错误码0002的异常
1、我们需要先自己定义一个错误码的枚举。
public enum ErrorCode {
TEL_EXIST("0001","手机号重复"),
CARD_EXIST("0002","证件号重复"),
OTHER("9999","系统异常");
/**错误码 */
private String code;
/**错误描述 */
private String msg;
ErrorCode(){};
ErrorCode(String code, String msg){
this.code = code;
this.msg = msg;
};
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
2、我们需要自己定义一个异常类。
/**
* 自定义异常
*/
public class MyException extends RuntimeException{
/**错误码 */
private ErrorCode errorCode;
/**自定义错误描述 */
private String errorMsg;
MyException(){}
MyException(ErrorCode errorCode){
this.errorCode = errorCode;
}
MyException(ErrorCode errorCode, String errorMsg){
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public ErrorCode getErrorCode() {
return errorCode;
}
public void setErrorCode(ErrorCode errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
3、写demo自己手动抛异常测试
//手动抛出异常
public static void throwMyException(){
//throw new MyException(ErrorCode.TEL_EXIST);
throw new MyException(ErrorCode.CARD_EXIST);
//throw new NullPointerException();
}
//main方法捕获异常
public static void main(String[] args) {
Result result = new Result();
try {
throwMyException();
} catch (MyException e) {
ResultUtil(result, e);
LOGGER.error("系统异常" , e);
} catch (Exception e) {
ResultUtilOther(result, e);
LOGGER.error("未知异常:",e);
}
System.out.println(JSONObject.toJSONString(result));
}
//手动抛出异常处理类
public static void ResultUtil(Result result, MyException e){
result.setCode(e.getErrorCode().getCode());
String errorMsg = e.getErrorMsg();
if(StringUtils.isBlank(errorMsg)){
errorMsg = e.getErrorCode().getMsg();
}
result.setMsg(errorMsg);
}
//未知异常处理类
public static void ResultUtilOther(Result result,Throwable e){
result.setCode(ErrorCode.OTHER.getCode());
result.setMsg(ErrorCode.OTHER.getMsg());
}
//返回值
public class Result {
/**返回码 */
private String code;
/**返回描述 */
private String msg;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
4、通过观察自己抛出的 TEL_EXIST、CARD_EXIST等错误可以看到在main方法的第一个catch中可以捕获并构造了一个已知失败的响应;如果自己手动抛出了空指针则会被第二个catch到来构建一个未知的错误(代码异常或者其他异常);在这里需要注意的是打日志的时候不要把错误日志打印到控制台(比如不能用e.printStackTrace()),而且使用LOGGER.error的时候一定要用逗号隔开才能打印出来完整的错误堆栈信息,方面自己找出异常的点在哪里。