需求:小程序登陆时,后台须要将异常抛出,并将错误信息交给前台。spring
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; } }
if (student.getWechat() != null && !student.getWechat().getOpenid().equals(openId)) { throw new WechatLoginException("该学号已被其余微信账号绑定,请联系老师或者管理员解除绑定", HttpStatus.valueOf(509)); }
// 处理微信登陆的异常 @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()); }
后来,潘老师和张喜硕学长评论说这样写很差,由于开放异常信息
,异常的状态码只靠注释约束,当返回未知状态码前台不知道如何处理。小程序
根据潘老师的建议,作出以下修改:微信
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; } }
public class WechatLoginException extends RuntimeException { private int code; // 异常状态码 public WechatLoginException(HttpStatusEnum httpStatusEnum) { super(httpStatusEnum.getDescription()); code = httpStatusEnum.getCode(); } public int getCode() { return code; } }
throw new WechatLoginException(HttpStatusEnum.StudentISBinded);
//处理微信登陆的异常 @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
而张喜硕学长指出,spring-boot的HttpStatus枚举是不可扩展的,即我没法经过继承来增长自定义的http状态码测试
因此,此时陷入一个僵局,要么放弃使用自定义状态码,要么放弃使用ResponseEntity,这时,张喜硕学长说了一下他的解决方案,即不返回ResponseEntity了,而是注入HttpServletResponse,调取setStatus()直接改返回的状态码:this
// 处理微信登陆的异常 @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(); }
而后在小程序端测试,发现果真状态码能够变成了自定义的了
接着,就是在小程序端添加异常处理:url
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; } }
最后的效果:spa
总得来讲,此次收获仍是挺多的,遇到了很多问题,也对一些知识的盲区进行了探索和挖掘。虽然实现了需求,但以为小程序的异常处理仍是有些生硬
,还有改进的余地。code