全局异常处理
首先是异常错误码,用接口统一起来
/**
* 封装API的错误码
*/
public interface IErrorCode {
long getCode();
String getMessage();
}
public enum BizExceptionEnum implements IErrorCode {
/**
* 业务请求相关异常,基本上是返回给用户的
*/
INCORRECT_PARAMETER(20000L, "参数不正确"),
NO_RECORD(20001L, "没有记录,请核对查询条件"),
PARAMS_INVALID(20003L, "参数:{0}为必传项");
BizExceptionEnum(Long code, String message) {
this.code = code;
this.message = message;
}
private Long code;
private String message;
public void setCode(Long code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public long getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
public enum BizExceptionEnum implements IErrorCode {
/**
* 业务请求相关异常,基本上是返回给用户的
*/
INCORRECT_PARAMETER(20000L, "参数不正确"),
NO_RECORD(20001L, "没有记录,请核对查询条件"),
PARAMS_INVALID(20003L, "参数:{0}为必传项");
BizExceptionEnum(Long code, String message) {
this.code = code;
this.message = message;
}
private Long code;
private String message;
public void setCode(Long code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public long getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
这个错误码不止异常可以用,也可以用来返回
public enum ResultCode implements IErrorCode {
SUCCESS(200, "操作成功"),
FAILED(500, "服务器繁忙,请稍后再试"),
BUSINESS_FAILED(501, "业务异常,具体错误看下级状态码"),
LIMIT_REQ_FAILED(503, "服务器繁忙,请稍后再试"),
FAILED_UP_SERVER(505, "上游服务不可用"),
FAIL_MESSAGE(509, "服务器繁忙,请稍后再试"),
VALIDATE_FAILED(404, "参数检验失败"),
UNAUTHORIZED(401, "暂未登录或token已经过期"),
FORBIDDEN(403, "没有相关权限");
private long code;
private String message;
private ResultCode(long code, String message) {
this.code = code;
this.message = message;
}
public long getCode() {
return code;
}
public String getMessage() {
return message;
}
}
接下来就是自定义异常,很简单
public class BaseException extends RuntimeException {
private IErrorCode iErrorCode;
public BaseException() {
super();
}
public BaseException(IErrorCode exceptionEnum) {
super(exceptionEnum.getMessage());
this.iErrorCode=exceptionEnum;
}
public BaseException(IErrorCode exceptionEnum, Throwable cause) {
super(exceptionEnum.getMessage(), cause);
this.iErrorCode=exceptionEnum;
}
public BaseException(Throwable cause) {
super(cause);
}
public static void fail(IErrorCode exceptionEnum) {
throw new BaseException(exceptionEnum);
}
/**
* 断言flag为真,不是真就报错,返回message
*/
public static void assertTrue(boolean flag, IErrorCode exceptionEnum) {
if (!flag) {
fail(exceptionEnum);
}
}
/**
* 断言flag为假,不是false就报错
*/
public static void assertFalse(boolean flag, IErrorCode exceptionEnum) {
assertTrue(!flag, exceptionEnum);
}
public IErrorCode getiErrorCode() {
return iErrorCode;
}
}
里面加个两个断言方法,用起来方便一点。
接下来就是全局异常的控制,也是采用@ControllerAdvice注解
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
private static final String PARAM_PREFIX = "param:{}";
/**
*自定义异常处理
* @return
*/
@ExceptionHandler(ApiException.class)
public CommonResult exception(HttpServletRequest request,ApiException e){
log.error(PARAM_PREFIX, request.getRequestURI(), e);
return CommonResult.failed(e.getMessage());
}
}
@RestControllerAdvice和@RestController一样,就是@ResponseBody+@ControllerAdvice,不用再单独写了。
that’s all