优雅代码-异常捕获
异常捕获
程序中各层都会出现大量的异常,对应try catch finally就会大量出现,导致大量的冗余代码,甚至可能影响代码可读性,这种情况需要一个全局异常处理来解决
推荐理由
- 通过少量的异常处理代码,可以解决代码冗余
- 方便统一管理异常
定义全局异常类
定义个全局异常类,和几个常见异常处理的定制方法
/**
* 全局异常处理器
*
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 参数校验异常处理
*
* @param exception
* @return
*/
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public Result methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) {
String message = exception.getBindingResult().getFieldError().getDefaultMessage();
log.warn("参数校验不通过 message={}", message);
Result result = new Result(Result.Error, message);
result.setRequestId(RequestUtils.getRequestId());
return result;
}
/**
* 处理自定义业务异常
*
*/
@ExceptionHandler(value = BusinessException.class)
public Result bizExceptionHandler(BusinessException exception) {
log.warn(" message=", exception.getMessage());
Result result = new Result(exception.getCode, exception.getMessage);
result.setRequestId(RequestUtils.getRequestId());
return result;
}
/**
* 处理自定义系统异常
* 需要监控机制触发报警
*/
@ExceptionHandler(value = SystemException.class)
public Result systemException(SystemException exception) {
log.error("系统异常 Exception=", exception);
Result result = new Result(Result.Error, "系统异常,请稍后再试");
result.setRequestId(RequestUtils.getRequestId());
return result;
}
/**
*处理未知异常
* 需要监控机制触发报警
*/
@ExceptionHandler(value = Exception.class)
public Result exceptionHandler( Exception exception) {
log.error("系统异常 Exception=", exception);
Result result = new Result(Result.Error, "系统异常,请稍后再试");
result.setRequestId(RequestUtils.getRequestId());
return result;
}
}
到此所有的异常几乎都不需要再每一个接口中捕获处理,如有特殊需要处理的异常只需要在代码简单捕获然后转成自定义业务异常或者自定义系统异常,最终还是交给全局异常处理。
自定义异常
自定异常
@Data
public class BaseException extends RuntimeException {
private String code;
private String message;
public BaseException(String code, String message) {
super(message);
this.code = code;
this.message = message;
}
public BaseException(String message) {
super(message);
this.message = message;
}
public BaseException(BaseErrorEnum errorEnum) {
super(errorEnum.getName());
this.message = errorEnum.getName();
this.code = errorEnum.getCode();
}
}
业务异常
/**
*业务异常,继承与基础异常
*/
@Data
public class BusinessException extends BaseException {
public BusinessException(String code, String message) {
super(code,message);
this.code = code;
this.message = message;
}
public BusinessException(String message) {
super(code,message);
this.message = message;
}
public BusinessException(BusinessErrorEnum errorEnum) {
super(errorEnum.getCode(),errorEnum.getName());
this.message = errorEnum.getName();
this.code = errorEnum.getCode();
}
}
自定义系统异常
@Data
public class SystemException extends BaseException {
public SystemException(String code, String message) {
super(code,message);
this.code = code;
this.message = message;
}
public SystemException(String message) {
super(code,message);
this.message = message;
}
public SystemException(SystemErrorEnum errorEnum) {
super(errorEnum.getCode(),errorEnum.getName());
this.message = errorEnum.getName();
this.code = errorEnum.getCode();
}
}
自定义异常枚举
自定义业务异常枚举
@Data
public enum BusinessErrorEnum {
NOT_DATA_ERROR("1001", "查询的数据不存在"),
NOT_NULL_PARAM_ERROR("1002", "请求参数不能为空"),
;
private String message;
private String code;
}
自定义系统异常
@Data
public enum SystemErrorEnum {
CONNECTION_TIME_OUT_ERROM("9001", "连接超时"),
;
private String message;
private String code;
}
CLC