需求:小程序登录时,后台需要将异常抛出,并将错误信息交给前台。一、后台异常处理1.自定义微信登录异常 public class WechatLoginException extends RuntimeException { /** * @Description 自定义状态码 * 510: 未找到该学号或该学号的状态已冻结 * 509: 该学号已被其他微信帐号绑定,请联系老师或者管理员解除绑定 * 508: 该微信帐号已绑定学号,请解除绑定后重新登录 **/ private HttpStatus status = null; public WechatLoginException(String message, HttpStatus httpStatus) { super(message); status = httpStatus; } public HttpStatus getStatus() { return status; }}2.userService抛出异常 if (student.getWechat() != null && !student.getWechat().getOpenid().equals(openId)) { throw new WechatLoginException(“该学号已被其他微信帐号绑定,请联系老师或者管理员解除绑定”, HttpStatus.valueOf(509)); }3. 全局异常处理// 处理微信登录的异常@ExceptionHandler(WechatLoginException.class)public ResponseEntity<JsonErrorResult> wechatLoginHandler(HttpServletRequest request, WechatLoginException e){ logger.error(“微信登录异常:—Host {} invokes url {} ERROR: {}”, request.getRemoteHost(), request.getRequestURL(), e.getMessage()); return new ResponseEntity<>(new JsonErrorResult(request, e), e.getStatus());}存在的问题后来,潘老师和张喜硕学长评论说这样写不好,因为开放异常信息,异常的状态码只靠注释约束,当返回未知状态码前台不知道如何处理。二、改进根据潘老师的建议,做出如下修改:1. 添加异常状态枚举public enum HttpStatusEnum { StudentNotFound(“未找到该学生”, 601), StudentIsForzen(“该学生的状态已冻结”, 602), StudentISBinded(“该学号已被其他微信帐号绑定,请联系老师或者管理员解除绑定”, 603), WecahtIsBinded(“该微信帐号已绑定学号,请解除绑定后重新登录”, 604); private String description; private int code; private HttpStatusEnum (String description, int code) { this.description = description; this.code = code; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getCode() { return code; } public void setCode(int code) { this.code = code; }}2. 异常类修改,构造时传入枚举体public class WechatLoginException extends RuntimeException { private int code; // 异常状态码 public WechatLoginException(HttpStatusEnum httpStatusEnum) { super(httpStatusEnum.getDescription()); code = httpStatusEnum.getCode(); } public int getCode() { return code; }}3. service抛出异常throw new WechatLoginException(HttpStatusEnum.StudentISBinded);4. 全局异常处理//处理微信登录的异常@ExceptionHandler(WechatLoginException.class)public ResponseEntity<JsonErrorResult> wechatLoginHandler(HttpServletRequest request, WechatLoginException e){ logger.error(“微信登录异常:—Host {} invokes url {} ERROR: {}”, request.getRemoteHost(), request.getRequestURL(), e.getMessage()); return new ResponseEntity<>(new JsonErrorResult(request, e), e.getStatus());}然后这一步就出现了问题,使用ResponseEntity返回异常信息时,第二个参数需要传入HttpStatus,如图:而张喜硕学长指出,spring-boot的HttpStatus枚举是不可扩展的,即我无法通过继承来增加自定义的http状态码所以,此时陷入一个僵局,要么放弃使用自定义状态码,要么放弃使用ResponseEntity,这时,张喜硕学长说了一下他的解决方案,即不返回ResponseEntity了,而是注入HttpServletResponse,调取setStatus()直接改返回的状态码:// 处理微信登录的异常@ExceptionHandler(value = WechatLoginException.class)public String WechatLoginExceptionHandler(HttpServletRequest request, HttpServletResponse response, WechatLoginException e) throws IOException { logger.error(“微信登录异常:—Host {} invokes url {} ERROR: {}”, request.getRemoteHost(), request.getRequestURL(), e.getMessage()); response.setStatus(e.getCode()); return e.getMessage();}然后在小程序端测试,发现果然状态码可以变成了自定义的了接着,就是在小程序端添加异常处理: public static handleHttpException(response: RequestSuccessCallbackResult) { let result = ‘’; switch (response.statusCode) { case 601: result = ‘未找到该学生’; break; case 602: result = ‘该学生的状态已冻结’; break; case 603: result = ‘该学号已被其他微信帐号绑定,请联系老师或者管理员解除绑定’; break; case 604: result = ‘该微信帐号已绑定学号,请解除绑定后重新登录’; } // 如果异常信息不为空,则显示提示信息,并且抛出异常 if (result != ‘’) { // 显示异常 wx.showToast({ title: result, icon: “none”, duration: Request.duration }); throw response; } }最后的效果:总结总得来说,这次收获还是挺多的,遇到了不少问题,也对一些知识的盲区进行了探索和挖掘。虽然实现了需求,但觉得小程序的异常处理还是有些生硬,还有改进的余地。