业务成长记录:它错任他错

本文介绍了一种在后端开发中处理异常的有效方法。作者通过实际案例分享了如何定义异常、使用Spring框架进行异常拦截及处理,并展示了如何通过枚举类定制异常信息以提高系统的健壮性和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

向成为一名不加班的程序员进发,从简单的开始。

怎么办,又有报异常?

大佬:你看一下log,这里报异常了,你怎么不提醒?

小糖:哦哦,我把bug改一下。

大佬:不是,你怎么不提醒有异常。

小糖:嗯?

异常是要报出来的

刚刚接触后台的时候,因为有过Android工作的编程经历,java还算是顺手,编码工作还算顺利。但对于异常,我常做的就是不让它报出来,封得死死的(小白写法),一个App报出了异常,一定不让用户发现。但是后台就不是这么回事了。有了问题一定让他报错来,记录在log里面看,也要给前端提醒。返回类有返回码。我的成功返回码是000000。其他的返回码都是异常,不管是查不到改用户,还是手机号码输入错误,这些都可以用来异常来处理。

定义异常


所报的异常都是所知道的层,比如没有该资源,比如,找不到该用户。虽然他们是可以按照顺利的流程返回到Controller层,但是这么本可以在查询不到该用户的时候就结束流程,再一步步返回到controller层是不是太浪费了。

给出一个规则:在不符合正常路线的流程都可视为异常。

异常正确处理

这里用到了spring的拦截异常处理,通过他返回所有的异常。

拦截异常

spring中,有一个抽象类,HandlerExceptionResolver可以拦截到系统中报出的所有异常

public class HealthHandlerExceptionResolver implements HandlerExceptionResolver {

    public Logger logger = Logger.getLogger(this.getClass());

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, 
            Object handler, Exception ex) {
     
    }
}复制代码

所有爆出来的异常都会再次到这个方法来。Exception 这个字段 就是我们报错的异常。

而我们做的就是正确处理这个异常字段

异常的特别关照

在拦截异常中,是Exception类型,提醒的也自然是这个类型。我们对这个类进行处理

继承此类,子类BaseException

public class BaseException extends Exception {

    private static final long serialVersionUID = 1L;
    
    private String logMsg;
    
    //错误码 枚举
    private ErrorCode code; 

    public BaseException(ErrorCode code) {
        super();
        this.code = code;
    }

    public BaseException(ErrorCode code,String logMsg,String msg){
        super();
        this.code = code;
        this.code.setMsg(msg);
        this.logMsg=logMsg;
    }


    public BaseException(ErrorCode code,String logMsg) {
        super();
        this.code = code;
        this.logMsg=logMsg;
    }

    public String getLogMsg() {
        return logMsg;
    }

    public void setLogMsg(String logMsg) {
        this.logMsg = logMsg;
    }

    public ErrorCode getCode() {
        return code;
    }

    public void setCode(ErrorCode code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
    
    public String parseString() {
        //ResponseInfo 是返回类
       return JSONObject.toJSONString(new ResponseInfo(code));
    }

}复制代码

错误码的枚举类

public enum ErrorCode {
   companyError("70006+","手机号码错误"),
   weChatLoginError("600002","微信登录异常"),
   permissionDenied("900005","没有权限,拒绝访问" );
   
   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;
   }

   private ErrorCode(String code, String msg) {
      this.code = code;
      this.msg = msg;
   }
 
}复制代码

在BaseException类的构造方法中

public BaseException(ErrorCode code) {
        super();
        this.code = code;
    }复制代码

通过填入对应的错误码,再通过spring的拦截器,识别并返回json

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
   String returnInfo=null;
if(ex instanceof TTException) { //识别出对应的异常
   logger.info(ex.toString());
   returnInfo=((BaseException)ex).parseString(); //返回String类型 json
}else {
   logger.error("SystemException!", ex);
   returnInfo= "{\"returnCode\":\"999999\",\"returnMsg\":\"系统错误\"}";
   
}
try {
   //利用HttpServletResponse 返回
   ResponseWriteUtil.writerJSONInfo(returnInfo, response);
} catch (IOException e1) {
   e1.printStackTrace();
}
      return new ModelAndView();
  }复制代码

给前端输出数据的方法

public static void writerJSONInfo(String json,HttpServletResponse response) throws IOException {
   PrintWriter pw=getWriter(response,"application/json;charset=utf-8");
   logger.info("return info is "+json);
   pw.print(json);
   pw.flush();
   pw.close();
}复制代码

继承BaseException的的login登录异常类

public class TTException extends BaseException {
    //query_not_found_openId 可以用做log记录
    public TTException(ErrorCode code, String query_not_found_openId) {
        super(code);
    }

    @Override
    public String toString() {
        return "LoginException : "+this.getLogMsg();
    }

}复制代码

使用

throw new TTException(ErrorCode.nosuchuser,phone + "未注册");
{"returnCode":"800001","returnMsg":"手机号码未被注册","serialNum":"957c0d76-2d7e-45cd-898c-f49e0d74e6cc"}复制代码

一个错误码,多种提示

现在有了新的需求,比如:A用手机号注册一个身份证,发现被占用了,要提示出176****被占用。这个该怎么办呢,枚举类都已经定了版。这个时候,我要做的是对这个提示做一下手脚了。错误枚举类,只要它的错误码,提示类容另外填入。

同样是实现BaseException的继承

public class RegisterDulipcaException extends BaseException{
   
   private String msg;
   
   private static final long serialVersionUID = 1L;

   public ZCRegisterDulipcaException(ErrorCode code) {
      super(code);
   }
   
   public ZCRegisterDulipcaException(ErrorCode code,String logMsg,String msg) {
      super(code,logMsg);
      this.msg=msg; //变动的提示信息
   }

    //对错误数据进行处理
   public String parseString() {
      ResponseInfo returnResponseInfo=new ResponseInfo(getCode());
      returnResponseInfo.setReturnMsg(msg);
       return JSONObject.toJSONString(returnResponseInfo);
    }
   
}复制代码

返回类关于ErrorCode的构造方法

public ResponseInfo(ErrorCode responseCode) {
   super();
   this.returnCode = responseCode.getCode();
   this.returnMsg = responseCode.getMsg();
   this.serialNum = UUID.randomUUID().toString();
}复制代码

修改掉returnMsg

public void setReturnMsg(String returnMsg) {
   this.returnMsg = returnMsg;
}复制代码

这样子就能做大灵活变动。

------------------------------------------------------------------------------------------------

以上就是本次的总结,都是看大佬的代码,我只是给自己做个总结,学习。谢谢观看


转载于:https://juejin.im/post/5c973daf5188252d932084f2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值