Vben Admin 源碼學習:狀態管理-錯誤日誌

0x00 前言

本文將對 Vue-Vben-Admin 的狀態管理實現源碼進行分析解讀,耐心讀完,相信您一定會有所收穫!

0x01 errorLog.ts 錯誤日誌

文件 src\store\modules\errorLog.ts 聲明導出一個store實例 useErrorLogStore 、一個方法 useErrorLogStoreWithOut()用於沒有使用 setup 組件時使用。

// 錯誤日誌存儲實例
export const useAppStore = defineStore({
  id: 'app-error-log',  
  state: {},
  getters: {}
  actions:{}   
});

export function useErrorLogStoreWithOut() {
  return useErrorLogStore(store);
}

State / Getter

狀態對象定義了錯誤日誌資訊數組、錯誤日誌資訊總數。

state: (): ErrorLogState => ({
  errorLogInfoList: null, // Nullable<ErrorLogInfo[]>
  errorLogListCount: 0,
}), 
getters: {
  // 獲取錯誤日誌  默認空數組
  getErrorLogInfoList(): ErrorLogInfo[] {
    return this.errorLogInfoList || [];
  },
  // 獲取錯誤日誌總數量
  getErrorLogListCount(): number {
    return this.errorLogListCount;
  },
},

errorLogInfoList 是一個名為 ErrorLogInfo 對象數組,記錄了錯誤詳細資訊,包含錯誤類型、錯誤產生錯文件資訊、錯誤名稱、錯誤資訊、調用堆棧資訊、錯誤詳情、頁面url、錯誤發生時間。

export interface ErrorLogInfo { 
  type: ErrorTypeEnum; // 錯誤類型
  file: string;  // 產生錯誤文件
  name?: string; // 錯誤名稱
  message: string; // 錯誤資訊
  stack?: string; // 調用堆棧資訊
  detail: string; // 錯誤詳情
  url: string; // 頁面url
  time?: string; // 發生時間
}

錯誤類型有4種,分別為 Vue異常腳本錯誤靜態資源異常promise異常

// 錯誤類型
export enum ErrorTypeEnum {
  VUE = 'vue',
  SCRIPT = 'script',
  RESOURCE = 'resource',
  AJAX = 'ajax',
  PROMISE = 'promise',
}

Actions

addErrorLogInfo 方法用於添加錯誤日誌,接受類型為ErrorLogInfo 的參數,使用 展開語法(Spread syntax) 簡潔的構造方式進行數組和對象構造。

  1. 更新錯誤日誌時間屬性。
  2. 將日誌資訊加入名為 errorLogInfoList 的數組中。
  3. 同時更新錯誤日誌總數(errorLogListCount) +1
addErrorLogInfo(info: ErrorLogInfo) {
  const item = {
    ...info,
    time: formatToDateTime(new Date()),
  };
  this.errorLogInfoList = [item, ...(this.errorLogInfoList || [])];
  this.errorLogListCount += 1;
},

setErrorLogListCount 方法用於重置錯誤日誌總數數值。

setErrorLogListCount(count: number): void {
  this.errorLogListCount = count;
},

addAjaxErrorInfo 方法用於在ajax請求錯誤後觸發,將返回的錯誤資訊格式化後,調用 addErrorLogInfo方法將其添加至系統全局數組中。

addAjaxErrorInfo(error) {
  const { useErrorHandle } = projectSetting;
  if (!useErrorHandle) {
    return;
  }
  const errInfo: Partial<ErrorLogInfo> = {
    message: error.message,
    type: ErrorTypeEnum.AJAX,
  };
  if (error.response) {
    ...
  }
  this.addErrorLogInfo(errInfo as ErrorLogInfo);
},

需要在項目配置 src/settings/projectSetting.ts中開啟,將useErrorHandle屬性值設置 true ,默認不開啟。

// src/settings/projectSetting.ts

// 是否使用全局錯誤捕獲
useErrorHandle: true, 

使用 Partial 將類型定義的所有屬性都修改為可選。

聲明了一個錯誤日誌對象,僅定義了類型和消息兩個屬性值。
其餘的屬性值通過對 error.response 對象內容進行解構,然後進行對象屬性賦值。

  const errInfo: Partial<ErrorLogInfo> = {
    message: error.message,
    type: ErrorTypeEnum.AJAX,
  };
  if (error.response) {
    const {
      config: { url = '', data: params = '', method = 'get', headers = {} } = {},
      data = {},
    } = error.response;
    errInfo.url = url;
    errInfo.name = 'Ajax Error!';
    errInfo.file = '-';
    errInfo.stack = JSON.stringify(data);
    errInfo.detail = JSON.stringify({ params, method, headers });
  }

最後調用addErrorLogInfo方法,添加錯誤日誌資訊。

this.addErrorLogInfo(errInfo as ErrorLogInfo);

0x02 📚參考

“展開語法(Spread syntax)”,MDN