1 我和前端开发一次互相撕逼甩锅2 背景介绍
最近我们项目新开发了 APP,有一个功能需要获取用户的收集型号、通讯录权限,定位信息等,然鹅如果当用户关闭了相关的权限后,没有获取到用户信息,就会触发一个 bug,然后 app 会有一个弹窗。
3 问题分析
问题的直接原因是移动端没有获取到值,然后就将undefined传给了后端,我们后端定义的值类型是Integer,结果类型转换失败报错。
NumberFormatException: For input string
其实如果前端做了异常兜底或者后端做了统一异常处理,也不会有 app 的弹框了。
其实前后端都有问题,后端开发和前端开发开始甩锅撕逼了
感觉双方说的都好有道理,谁也说服不了谁。但是关于目标大家达成一致:坚决不能让用户看到这种类型的弹窗异常。
既然说服不了对方,就只能从更深入的分析问题,看看更合理的解法
通用异常的处理方式
为了统一异常处理,一般我们都是 API 统一返回一套数据格式
{
"code": "00000", // 00000代表正常,其他表示异常。
"message": "System exception" // message,错误提示消息
"data": "xx" // 正常数据
}
我们确定好类型后,就可以把后端加上统一异常处理;代码如下
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* 处理自定义异常
*
* @param e
* @return
*/
@ExceptionHandler(CustomException.class)
public Result handlerImCustomException(CustomException e) {
log.error("自定义异常:{}", e.getMessage(), e);
return new Result().buildFail(e);
}
/**
* 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常,详情继续往下看代码
*
* @param e
* @return
*/
@ExceptionHandler(BindException.class)
public Result BindExceptionHandler(BindException e) {
String message = e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
log.error("请求校验异常 BindException message:{} exception:{}", message, e.getMessage(), e);
return new Result().buildFail(message);
}
/**
* 处理参数校验异常
*
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
String message = e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
log.error("校验参数异常 message:{} exception:{}", message, e.getMessage(), e);
return new Result().buildFail(message);
}
/**
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public Result handlerConstraintViolationException(ConstraintViolationException e) {
String message =
e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
log.error("校验参数异常 message:{} exception:{}", message, e.getMessage(), e);
return new Result().buildFail(message);
}
/**
* 其他异常处理
*
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public Result handler(Exception e) {
log.error("系统异常", e);
return new Result().buildFail(CustomExceptionEnum.FAIL);
}
}
总结
后端要有全局异常处理机制
© 版权声明
THE END
暂无评论内容