全局异常处理

我们当项目变得比较大的时候,开始不可避免添加全局异常处理。主要为了针对项目能够进行统一的管理,这里我将异常处理基本结构写出供大家参考。

1、异常处理主要针对是异常处理的捕获类和对异常处理的具体处理方式,这里我将异常中简单分为自定义异常和其他异常。

@RestControllerAdvice
public class GlobalExceptionHandler extends BaseGlobalExceptionHandler {


    @ExceptionHandler(value =Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @Override
    public DefaultErrorResultVO handleOtherException( Exception e,HttpServletRequest request){
        return super.handleOtherException( e,request);
    }

    @ExceptionHandler(value =BaseCustomException.class)
    @ResponseStatus(HttpStatus.OK)
    @Override
    public ResponseEntity<DefaultErrorResultVO> handleCustomException(BaseCustomException e,
                                                                      HttpServletRequest request){
        return super.handleCustomException( e,request);
    }


}

public abstract class BaseGlobalExceptionHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());



    /**
     * 处理参数封装错误时异常
     */
    protected DefaultErrorResultVO handleOtherException(Exception e,
                                                                      HttpServletRequest request) {
        logger.error("handleOtherException uri:{} cause by", request.getRequestURI(), e);
        return DefaultErrorResultVO.failure(ResultCode.INNER_INTERFACE_EXCEPTION, e, HttpStatus.OK);
    }


    /**
     *处理自定义异常
     */
    protected ResponseEntity<DefaultErrorResultVO> handleCustomException(BaseCustomException e,
                                                                         HttpServletRequest request){
        logger.error("handleCustomException uri:{},exception:{},caused by", request.getRequestURI(), e.getClass(), e.getMessage());
        DefaultErrorResultVO failure = DefaultErrorResultVO.failure(e);
        return ResponseEntity.status(HttpStatus.valueOf(failure.getStatus())).body(failure);
    }
}

2、这里将异常处理的封装实体类贴出

@Data
public class DefaultErrorResultVO {

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * HTTP 响应状态码
     */
    private Integer status;

    private String error;
    /**
     * 异常堆栈精简信息
     */
    private String message;
    /**
     * 自定义的返回值编码
     */
    private Integer code;

    /**
     * 调用接口路径
     */
    private String path;

    /**
     * 异常的名字
     */
    private String exception;

    /**
     * 异常错误传递的数据
     */
    private Object errors;

    /**
     * 发生时间
     */
    private String time;

    public static DefaultErrorResultVO failure(ResultCode resultCode, Throwable e, HttpStatus httpStatus, Object errors) {
        DefaultErrorResultVO failure = DefaultErrorResultVO.failure(resultCode, e, httpStatus);
        failure.setErrors(errors);
        return failure;
    }

    public static DefaultErrorResultVO failure(ResultCode resultCode,Throwable e,HttpStatus httpStatus){
        DefaultErrorResultVO resultVO = new DefaultErrorResultVO();
        resultVO.setCode(resultCode.getCode());
        resultVO.setMessage(resultCode.getMessage());
        resultVO.setStatus(httpStatus.value());
        resultVO.setError(httpStatus.getReasonPhrase());
        resultVO.setException(e.getMessage());
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String path = request.getRequestURI();
        resultVO.setPath(path);
        resultVO.setTime(formatter.format(LocalDateTime.now()));
        return resultVO;
    }

    public static DefaultErrorResultVO failure(BaseCustomException e) {
        BusinessExceptionEnum exceptionEnum = BusinessExceptionEnum.getByClass(e.getClass());
        if(Objects.nonNull(exceptionEnum)){
            return DefaultErrorResultVO.failure(exceptionEnum.getResultCode(), e, HttpStatus.OK);
        }
        DefaultErrorResultVO errorResultVO = DefaultErrorResultVO.failure(e.getResultCode() == null ? ResultCode.FAIL : e.getResultCode(), e, HttpStatus.OK, e.getData());
        String message = e.getMessage();
        if (!StringUtils.isEmpty(message)) {
            errorResultVO.setMessage(message);
        }
        return errorResultVO;
    }
}

3、对异常自定义的方式

@Data
public class BaseCustomException extends RuntimeException {
    protected String code;

    protected String message;

    protected ResultCode resultCode;

    protected transient Object data;


    public BaseCustomException(){

    }

    public BaseCustomException(String message) {
        this();
        this.message = message;
    }

    public BaseCustomException(String format, Object... objects) {
        this();
        this.message = String.format(format, objects);
    }

    public BaseCustomException(ResultCode resultCode,Object data){
        this(resultCode);
        this.data = data;
    }

    public BaseCustomException(ResultCode resultCode) {
        this.resultCode = resultCode;
        this.code = resultCode.getCode().toString();
        this.message = resultCode.getMessage();
    }
}

4、具体定义异常对基本异常进行统一继承,能够对自定义异常更好统一管理

public class ParamInvalidException extends BaseCustomException {

    public ParamInvalidException(){
        super();
    }

    public ParamInvalidException(Object data){
        super.data = data;
    }

    public ParamInvalidException(ResultCode resultCode) {
        super(resultCode);
    }

    public ParamInvalidException(ResultCode resultCode,Object data){
        super(resultCode,data);
    }

    public ParamInvalidException(String msg) {
        super(msg);
    }

    public ParamInvalidException(String formatMsg, Object... objects) {
        super(formatMsg,objects);
    }

}

5、对于异常的枚举处理类

public enum BusinessExceptionEnum {

    PARAM_INVALID(ParamInvalidException.class,ResultCode.PARAM_INVALID);

    private Class<? extends BaseCustomException> aClass;
    private ResultCode resultCode;

    BusinessExceptionEnum(Class<? extends BaseCustomException> aClass, ResultCode resultCode) {

        this.aClass = aClass;
        this.resultCode = resultCode;
    }

    public Class<? extends BaseCustomException> getaClass() {
        return aClass;
    }

    public static BusinessExceptionEnum getByClass(Class<? extends BaseCustomException> aClass){
        for (BusinessExceptionEnum businessException : BusinessExceptionEnum.values()) {
            if (businessException.aClass.equals(aClass)) {
                return businessException;
            }
        }
        return null;
    }

    public ResultCode getResultCode() {
        return resultCode;
    }
}

6、对弈异常具体编码的定义

public enum ResultCode {
    SUCCESS(200, "success"),
    FAIL(-1, "fail"),



    PARAM_INVALID(-1000, "param invalid"),

    USER_UN_LOGIN(-2000, "user no login"),


    SIGN_INVALID(-3000, "sign invalid"),
    SYSTEM_EXCEPTION(-4000, "system error"),
    INNER_INTERFACE_EXCEPTION(-5000, "inner interface exception"),;


    private Integer code;
    private String message;

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    ResultCode(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public static String getMessage(Integer code) {
        for (ResultCode resultCode : ResultCode.values()) {
            if (resultCode.getCode().equals(code)) {
                return resultCode.getMessage();
            }
        }
        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值