问题提出

一个项目,写了很多自定义的异常,都是继承自RuntimeException
01 自定义异常细分过多.png

每个自定义异常的成员构成一样,主要有两个成员变量。一个Integer类型的stateCode,一个String类型的stateInfo

import lombok.Getter;

@Getter
public class CustomerOrderControllerException extends RuntimeException {
    private static final long serialVersionUID = 7041929752847179080L;

    private Integer stateCode;
    private String stateInfo;

    public CustomerOrderControllerException(CustomerOrderControllerStateEnum customerOrderControllerStateEnum) {
        super(customerOrderControllerStateEnum.getStateInfo());
        this.stateCode = customerOrderControllerStateEnum.getStateCode();
        this.stateInfo = customerOrderControllerStateEnum.getStateInfo();
    }

    public CustomerOrderControllerException(Integer stateCode, String errMsg) {
        super(errMsg);
        this.stateCode = stateCode;
        this.stateInfo = errMsg;
    }
}

至于为什么每个service和controller都写一个异常,一方面是因为没有经验导致的问题,另一方面是因为过度的强迫症。

现在想统一捕获这些自定义的异常,捕获一个异常的常见写法如下:

02 常见的异常捕获写法.png

标准写法,红线标出的部分是需要被捕获的异常。

那么问题来了,我写的自定义异常有很多,一个个写异常捕获是崩溃的,并且这些自定义异常的成员变量都一样,果断应该抽象出一个父类,然后捕获父类异常

问题解决

根据业务场景,抽象出了一个公共异常类。为了在捕获公共异常类时,可以标注出是哪个子类异常,为公共异常类和子异常类添加了一个成员变量exceptionClassName

公共异常类

import lombok.Getter;

@Getter
public class SellException extends RuntimeException {
    private static final long serialVersionUID = 2930168342534521500L;

    private String exceptionClassName;

    private Integer stateCode;
    private String stateInfo;

    public SellException(String message) {
        super(message);
    }
}

子异常类

子异常类使用

this.getClass().getName();

在子异常类被创建时,获取当前异常类的类名

子异常类如下:

import lombok.Getter;

@Getter
public class CustomerOrderControllerException extends SellException {
    private static final long serialVersionUID = 7041929752847179080L;

    private String exceptionClassName = this.getClass().getName();

    private Integer stateCode;
    private String stateInfo;

    public CustomerOrderControllerException(CustomerOrderControllerStateEnum customerOrderControllerStateEnum) {
        super(customerOrderControllerStateEnum.getStateInfo());
        this.stateCode = customerOrderControllerStateEnum.getStateCode();
        this.stateInfo = customerOrderControllerStateEnum.getStateInfo();
    }

    public CustomerOrderControllerException(Integer stateCode, String errMsg) {
        super(errMsg);
        this.stateCode = stateCode;
        this.stateInfo = errMsg;
    }
}

最后捕获公共异常类:

// 拦截卖家异常
    @ExceptionHandler(value = SellException.class)
    @ResponseBody
    public ResultVO handlerSellerException(SellException e) {
        return ResultVOUtil.error(e.getExceptionClassName(), e.getStateCode(), e.getStateInfo());
    }

其中,ResultVO:

@Data
public class ResultVO<T> {
    // 表示异常的ResultVO需要使用此成员变量
    private String exceptionClassName;

    private Integer code;
    private String msg;

    // 具体内容
    private T data;
}

其中,ResultVOUtil工具类:

// 表示异常的ResultVO
    public static ResultVO error(String exceptionClassName, Integer stateCode, String errMsg) {
        ResultVO resultVO = new ResultVO();
        resultVO.setExceptionClassName(exceptionClassName);
        resultVO.setCode(stateCode);
        resultVO.setMsg(errMsg);
        return resultVO;
    }

捕获的异常类返回结果:

03 异常类捕获返回结果.png

问题思考

这个项目中,写了过多的自定义异常(每个service和controller都写一个异常),这种过多的细分是不好的,应该以一个业务场景来定义一个异常。


JellyfishMIX
34 声望2 粉丝

coder