1. 程式人生 > >基於Spring Boot的統一異常處理設計

基於Spring Boot的統一異常處理設計

基於Spring Boot的統一異常處理設計

作者: Grey

原文地址:https://www.cnblogs.com/greyzeng/p/11733327.html

Spring Boot中,支援RestControllerAdvice統一處理異常,在一個請求響應週期當中,如果Controller,Service,Repository出現任何異常,都會被RestControllerAdvice機制所捕獲,進行統一處理。

進行統一異常處理的目的也就是為了將千奇百怪的異常資訊轉換成使用者可識別的錯誤資訊

統一異常攔截器

@RestControllerAdvice
@Slf4j
public class GlobalExceptionTranslator {

}

系統中的兩類異常處理

第一類:業務自定義的異常,遇到這種異常,攔截器記錄後,將業務異常自己的資訊丟擲。

@ExceptionHandler(BusinessException.class)
public JSONObject handleError(BusinessException e) {
    log.error("Business Exception {}", getStackTraceAsString(e));
    return error(e);
}

第二類:未定義異常,攔截器負責統一遮蔽原來的異常資訊,轉為伺服器內部異常丟擲。

@ExceptionHandler(Throwable.class)
public JSONObject handleError(Throwable undefined) {
    log.error("Internal Server Error {}", getStackTraceAsString(undefined));
    return error(new BusinessException(FAILURE));
}

呼叫者收到error的結果後,直接顯示msg內容為使用者可見的錯誤資訊即可。

如何自定義一個業務異常

在業務開發中,通常無需進行Try catch處理,有業務異常直接丟擲即可。如果需要定義一類通用的異常,則需要在自己業務模組下新建異常類,繼承於 BusinessException


public class PaymentException extends BusinessException {

    //重寫建構函式,從而定義該自定義異常的使用者可見的錯誤資訊
    public PaymentException() {
        super("支付失敗");
        
    }
}

如何自定義一個框架級異常

在系統框架層面,已經預定義了一些常見的異常類,如:

類名 定義 預置錯誤資訊
PermissionDenyException 使用者訪問未授權的內容 許可權不足
ServiceNotFoundException 呼叫微服務失敗 呼叫相關服務失敗
其他異常 ... ...

在定義框架級異常時,除了需要編寫異常類之外,如需要前端根據error CODE做對應的處理,就可以在ResultCode中增加定義。示例如下:

@Getter
@AllArgsConstructor
public enum ResultCode {

    /**
     * 操作成功
     */
    SUCCESS(HTTP_OK, "操作成功"),
    /**
     * 因程式內部錯誤操作失敗(如不指定,則預設這個異常)
     */
    FAILURE(HTTP_INTERNAL_ERROR, "系統執行異常,請聯絡管理員"),
    /**
     * 使用者訪問未授權的內容
     */
    UN_AUTHORIZED(HTTP_UNAUTHORIZED, "許可權不足"),

    /**
     * 呼叫微服務失敗
     */
    NOT_FOUND(HTTP_NOT_FOUND, "呼叫相關服務失敗");

    final int code;

    final String msg;
}

一個框架級異常的實現類


public class PermissionDenyException extends BusinessException {
    public PermissionDenyException() {
        super(UN_AUTHORIZED);
    }
}

如需要框架對該異常定義統一的策略,則需要在GlobalExceptionTranslator實現該策略,示例如下:

public class GlobalExceptionTranslator {   
    @ExceptionHandler(NewGlobalException.class)
    public JSONObject handleError(NewGlobalException e) {
        // 這裡可以實現自定義的異常策略
        return error(new BusinessException(e.getResultCode(),e.getMessage()));
    }
}