微服務統一異常處理機制
阿新 • • 發佈:2019-01-04
公司專案用了比較完善的異常處理機制,在此做一個記錄。
核心註解:@[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進行捕捉。