Vue3學(xué)習(xí)與實(shí)踐 · 全局異常監(jiān)控

每個(gè)web項(xiàng)目上線后,難免會(huì)出現(xiàn)各種奇奇怪怪的bug,或網(wǎng)絡(luò),或系統(tǒng)無法,或兼容適配,或測試遺漏等等原因。為了能更快的定位問題,解決問題,所以添加前端異常監(jiān)控至關(guān)重要。本文就具體介紹一下怎么在Vue3項(xiàng)目中配置全局異常監(jiān)控。

ERROR異常監(jiān)控

一、方法介紹

在Vue項(xiàng)目中,錯(cuò)誤異常監(jiān)控可從以下三個(gè)方法入手:

1. JS全局onerror

特點(diǎn):

  • 全局監(jiān)聽所有JS錯(cuò)誤
  • 無法識別 Vue 組件信息
  • 可以捕獲一些 Vue 監(jiān)聽不到的錯(cuò)誤,如:異步錯(cuò)誤

語法:

window.onerror = function(message, source, lineno, colno, error) {
  console.log(message, source, lineno, colno, error)
  // do something
}

// or

window.addEventListener('error', function(event) { 
  console.log(event)
  // do something
})

參數(shù):

  • message:錯(cuò)誤消息(字符串)
  • source:引發(fā)錯(cuò)誤的腳本的URL(字符串)
  • lineno:發(fā)生錯(cuò)誤的行號(數(shù)值)
  • colno:發(fā)生錯(cuò)誤的行的列號(數(shù)值)
  • error:錯(cuò)誤對象(對象)

2. Vue配置方法errorHandler

特點(diǎn):

  • Vue全局錯(cuò)誤監(jiān)聽,所有組件錯(cuò)誤都會(huì)匯總到這里
  • errorCaptured 返回 false ,錯(cuò)誤會(huì)被提前攔截阻止,這里無法捕獲

配置:

app.config.errorHandler = (err, vm, info) => {
  console.log(err, vm, info)
  // do something
}

參數(shù):

  • err:具體錯(cuò)誤信息
  • vm:當(dāng)前錯(cuò)誤所在的Vue實(shí)例
  • info:Vue特定的錯(cuò)誤信息,錯(cuò)誤所在的生命周期鉤子

3. 生命周期鉤子errorCaptured

特點(diǎn):

  • 監(jiān)聽所有 下級 組件的錯(cuò)誤
  • 返回 false 會(huì)阻止錯(cuò)誤向上傳播

配置:

<script setup>
  import { onErrorCaptured } from 'vue'

  onErrorCaptured((err, vm, info)=>{
    console.log(err, vm, info)
    // do something
  })
</script>  

參數(shù)和全局 errorHandler 完全一致

二、方法封裝

  1. 新建 commonApi.js 文件,封裝 http 接口請求
// src/api/commonApi.js

import store from '@/store';

const osType = (function () {
  const ua = window.navigator.userAgent;
  if (/(Android)/.test(ua)) {
    return 1;
  }
  if (/(iPhone|iPad)/.test(ua)) {
    return 2;
  }
  return 3;
}());

const isProd = process.env.NODE_ENV === 'production';

export default {
  postErrorLogs(prams) {
    /*
    * project 發(fā)生項(xiàng)目 可自行定義
    * errorType 錯(cuò)誤類型: 1接口報(bào)錯(cuò) 2代碼報(bào)錯(cuò)
    * terminal 終端平臺: 1安卓 2ios 3web
    * */
    if (!isProd) return;
    return ajax({
      url: '/api/common/log/error',
      method: 'POST',
      data: {
        ...prams,
        userInfo: store.getters['User/getUserInfo'].userId || '',
        pageUrl: window.location.href,
        project: 'xxx',
        terminal: osType,
      },
    });
  },
}
  1. 新建 errorHandler.js 文件,封裝 error 監(jiān)聽方法
// src/common/errorHandler.js

import { nextTick } from 'vue';
import CommonApi from '@/api/CommonApi';

export default {
  errorHandler(err, vm, info) {
    nextTick(async () => {
      await CommonApi.postErrorLogs({
        errorType: 2, // 錯(cuò)誤類型: 1接口報(bào)錯(cuò) 2代碼報(bào)錯(cuò)
        errorInfo: err.toString(),
        note: `組件:${vm.$.vnode.type.__file} \n發(fā)生錯(cuò)誤:${err} \n所在生命周期:${info}`,
      });
    });
  },
  
  async onerror(message, source, lineno, colno, error) {
    await CommonApi.postErrorLogs({
      errorType: 2, // 錯(cuò)誤類型: 1接口報(bào)錯(cuò) 2代碼報(bào)錯(cuò)
      errorInfo: `錯(cuò)誤原因:${message}\n錯(cuò)誤URL: ${source}\n錯(cuò)誤行號: ${lineno}`,
    });
  },
};

三、項(xiàng)目配置

在入口文件 main.js 中配置監(jiān)控方法

// src/main.js

import { createApp } from 'vue'
import ErrorFn from './common/errorHandler';
import App from './App.vue'

const isProd = process.env.NODE_ENV === 'production';

// ...

const app = createApp(App)

if (isProd) {
  app.config.errorHandler = ErrorFn.errorHandler
  window.onerror = ErrorFn.onerror
}

// ...

app.mount('#app')

溫馨提示:

  1. onErrorCaptured 鉤子監(jiān)聽可以在一些業(yè)務(wù)比較重要的組件進(jìn)行配置,收集詳細(xì)錯(cuò)誤信息。
  2. 使用了 onErrorCaptured 建議返回 false,避免收集重復(fù)的錯(cuò)誤信息。
  3. errorHandleronErrorCaptured 不能收集異步錯(cuò)誤。
  4. Vue2 和 Vue3 中的使用方法類似,onErrorCaptured 是Vue3組合式API的方法,Vue2中使用 errorCaptured 鉤子即可。

《Vue3學(xué)習(xí)與實(shí)戰(zhàn)》系列


歡迎訪問:天問博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容