1. 程式人生 > >微服務統一異常處理機制

微服務統一異常處理機制

  公司專案用了比較完善的異常處理機制,在此做一個記錄。

  核心註解:@[email protected],這個百度資料有很多。

  為了讓下游呼叫接口出現異常時,明確知道發生了什麼錯誤,我們自己定義了一個統一的業務異常類BizExpection類,繼承自RuntimeExpection.

@Data
public class BizException extends RuntimeException {

    /**
     * code     返回碼
     * msg      返回碼描述
     * subCode  詳細返回碼
     * subMsg   詳細返回碼描述
     */
    protected int code;
    protected String msg;
    protected String subCode;
    protected String subMsg;

    public BizException(int code,String msg){
        this.code = code;
        this.msg = msg;
    }

    public BizException(String subCode, String subMsg) {
        super(subMsg);
        this.subCode = subCode;
        this.subMsg = subMsg;
    }

    public BizException(int code,String msg,String subCode,String subMsg){
        this.code = code;
        this.msg = msg;
        this.subCode = subCode;
        this.subMsg = subMsg;
    }

    public BizException() {
        super();
    }


}

  然後,我們具體的異常類繼承自這個統一異常類,假如欄位缺失異常:

public class MissRequiredParamException extends BizException {

    public static final MissRequiredParamException MCH_MISS_METHOD_NAME = new MissRequiredParamException("missing-method","缺少方法名引數");
   

    public MissRequiredParamException(String subCode, String subMsg) {
        super(subCode, subMsg);
        super.code = 40001;
        super.msg = "缺少必選引數";
    }

    public MissRequiredParamException() {
        super();
    }

  這樣,我們在發生錯誤時丟擲這個異常,例如

  if (StringUtils.isEmpty(this.version)){

     throw MissRequiredParamException.MCH_MISS_VERSION;
  }

  然後,由ExpectionHandler捕捉到這個異常,構造成微服務呼叫需要返回的物件:

@ControllerAdvice
@ResponseBody
@Slf4j
public class UserExceptionHandler<ServiceException extends BizException> {

    @ExceptionHandler(BizException.class)  //業務丟擲的異常
    public ResponseDto unknowHandler(ServiceException serviceException){
        ResponseDto responseDto = new ResponseDto();
        responseDto.setCode(serviceException.getCode());
        responseDto.setMsg(serviceException.getMsg());
        responseDto.setSubMsg(serviceException.getSubMsg());
        responseDto.setSubCode(serviceException.getSubCode());
        log.error("==>服務出現異常",serviceException);
        return responseDto;
    }

    @ExceptionHandler(Exception.class)  //系統丟擲的未知異常
    public ResponseDto unknowHandler(Exception exception){
        ResponseDto responseDto = new ResponseDto();
        responseDto.setCode(RespCode.UNKNOW_ERROR.value());
        responseDto.setMsg("服務不可用");
        responseDto.setSubCode("isp.unknow-error");
        responseDto.setSubMsg("服務暫不可用(業務系統不可用)");
        log.error("==>未知異常",exception);
        return responseDto;
    }

  這樣,我們可以根據情況來處理大部分可能出錯的地方;對於那些沒有想到的,未知的異常,會由第二個ExpectionHandler進行捕捉。