我的项目中,使用nacos作为服务发现与注册中心,请求通过gateway网关匹配url请求不同的api服务,api服务根据服务名请求具体的服务。gateway中利用webflux进行了异常处理,主要针对api不可达的异常。api中利用sentline及fegin的fallback进行了异常的处理。在具体的服务时,想要自定义一些异常,并且进行统一的捕获并返回,且返回的数据格式需要与正常的一致,避免给前端造成麻烦。
1.自定义的异常类
这里注意不要msg不要定义成message,因为RuntimeException 中定义了一个message的变量。
/**
* 自定义的运行时异常
* @author
* @date 2020-02-26 17:00
*
*/
public class BizException extends RuntimeException {
private Integer code;
private String msg;
private String developMsg;
private String uri;
public BizException(Integer code, String message) {
this.code = code;
this.msg = message;
}
public BizException(BizExceptionEnum bizExceptionEnum, String developMsg) {
this.code = bizExceptionEnum.getCode();
this.msg = bizExceptionEnum.getDesc();
this.developMsg = developMsg;
}
public BizException(BizExceptionEnum bizExceptionEnum) {
this.code = bizExceptionEnum.getCode();
this.msg = bizExceptionEnum.getDesc();
this.developMsg = bizExceptionEnum.getDesc();
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
public String getDevelopMsg() {
return developMsg;
}
public String getUri() {
return uri;
}
public void setCode(Integer code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setDevelopMsg(String developMsg) {
this.developMsg = developMsg;
}
public void setUri(String uri) {
this.uri = uri;
}
}
2.定义统一的返回类
import com.ruizhi.detection.common.restful.exception.BizException;
import lombok.Data;
/**
* @description: 统一的异常返回
* @Author:
* @Date: 2020/2/26 11:34
*/
@Data
public class ResponseDto<T> {
/**
* 状态码
*/
private Integer code;
/**
* 状态信息
*/
private String message;
/**
* 错误信息
*/
private String errorMessage;
/**
* 数据
*/
private T data;
public ResponseDto(Integer code, String message, T data) {
this.code = code;
this.data = data;
this.message = message;
}
public ResponseDto(BizException bizException) {
this.code = bizException.getCode();
this.message = bizException.getMsg();
this.errorMessage = bizException.getDevelopMsg();
}
}
3.定义异常的枚举
/**
* 异常的枚举类
* @author sys
* @updater
* @updateDate 2020-02-36 14:11
*/
public enum BizExceptionEnum {
/**
* 异常
*/
ID_NOT_NULL(50001, "ID不能为NULL"),
FIND_MODEL_BY_ID_ERROR(50002, "根据id查询数据时异常"),
DATA_NOT_EXIST(50003, "数据不存在"),
INVALID_ARGUMENT(50004, "无效的参数"),
UPDATE_ERROR(500016, "修改数据时异常!"),
ROLE_AUTH_ERROR(500017, "角色授权失败!");
private Integer code;
private String desc;
BizExceptionEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return this.code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getDesc() {
return this.desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
4.异常的捕获及统一返回
import javax.servlet.http.HttpServletRequest;
/**
* 统一捕获异常的
* @author
* @date 2020-02-26 17:24
*/
@ControllerAdvice
public class BizExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(BizExceptionHandler.class);
@ExceptionHandler({Exception.class})
public ResponseEntity<ResponseDto> handleException(Exception exception, HttpServletRequest request) {
final boolean isBizException = exception instanceof BizException;
logger.error("触发请求:[{}]时系统出现异常,异常类型:{}", request.getRequestURI(), isBizException ? "业务异常" : "系统异常");
BizException bizException = (BizException) exception;
ResponseDto responseT = new ResponseDto(bizException);
return new ResponseEntity<>(responseT, HttpStatus.OK);
}
}
5.service中抛出异常
try {
// 异常了
}catch (Exception e){
throw new BizException(BizExceptionEnum.DATA_NOT_EXIST, "根据id查询不到权限:id=" + permissionId);
}
这样返回的数据格式如下: