前端错误日志收集方案
前言
公司的項目上線出現問題后難以定位錯誤,研究過現存的錯誤監控方案,受限于特殊條件只能定制自己的錯誤收集方案。
基于以上背景我擼出來一個錯誤日志收集方案 - Ohbug。
歡迎各位大佬 star ~
監控錯誤
說起錯誤的捕獲,首先想到的是 try catch ,通過 catch 捕獲到錯誤后進一步做出處理
try {undefined.map(v => v); } catch(e) {console.log(e); // TypeError: Cannot read property 'map' of undefined } 復制代碼然而 try catch 對于異步產生的錯誤毫無感知
try {setTimeout(() => {undefined.map(v => v);}, 1000) } catch(e) {console.log(e); // TypeError: Cannot read property 'map' of undefined } 復制代碼并且在實際工作中我也不可能給所有代碼加上 try catch,所以能否捕獲全局的錯誤呢?
react componentDidCatch
React 16 提供了一個內置函數 componentDidCatch,使用它可以非常簡單的獲取到 react 下的錯誤信息
componentDidCatch(error, info) { console.log(error, info); } 復制代碼React 16 的異常/錯誤處理
vue errorHandler
指定組件的渲染和觀察期間未捕獲錯誤的處理函數。這個處理函數被調用時,可獲取錯誤信息和 Vue 實例。
Vue.config.errorHandler = function (err, vm, info) {// handle error// `info` 是 Vue 特定的錯誤信息,比如錯誤所在的生命周期鉤子// 只在 2.2.0+ 可用 } 復制代碼errorHandler
onerror vs addEventListener
對于沒有使用 react 或 vue 的項目可以通過 onerror 或 addEventListener 監控全局錯誤(當然使用 react 或 vue 的項目同樣可以)
onerror 或 addEventListener 都可以捕獲到一些未知的錯誤,然而這兩個有什么區別呢?
window.onerror = (msg, url, row, col, error) => {console.log({msg, url, row, col, error}); }; setTimeout(() => {undefined.map(v => v); }, 1000); 復制代碼 window.addEventListener('error', (e) => {console.log(e); }, true); 復制代碼除此之外,addEventListener 還可以捕獲資源加載錯誤、未 catch 的 promise 錯誤。
// 捕獲未 catch 的 promise 錯誤 window.addEventListener("unhandledrejection", e => {e.preventDefault();console.log(e); }); Promise.reject('promiseError'); 復制代碼ajax/fetch 錯誤監控
想要監控請求失敗,上面的方法肯定是不可取的了。
使用 axios 的小伙伴可以通過配置攔截器實現錯誤的監控。
// 添加請求攔截器 axios.interceptors.request.use(function (config) {// 在發送請求之前做些什么return config;}, function (error) {// 對請求錯誤做些什么return Promise.reject(error);});// 添加響應攔截器 axios.interceptors.response.use(function (response) {// 對響應數據做點什么return response;}, function (error) {// 對響應錯誤做點什么return Promise.reject(error);}); 復制代碼這里我采用了重新封裝 XMLHttpRequest/fetch 對象的方法實現對網絡請求的監控。
XMLHttpRequest
const AJAX = {// 記錄請求的 urlreqUrl: '',// 記錄請求的方法reqMethod: '',// 保存原生的 open 方法xhrOpen: window.XMLHttpRequest.prototype.open,// 保存原生的 send 方法xhrSend: window.XMLHttpRequest.prototype.send,init() {const that = this;window.XMLHttpRequest.prototype.open = function () {that.reqUrl = arguments[1];that.reqMethod = arguments[0];that.xhrOpen.apply(this, arguments);};window.XMLHttpRequest.prototype.send = function () {this.addEventListener('readystatechange', function () {if (this.readyState === 4) {if (!this.status || this.status >= 400) {// 錯誤收集}}});that.xhrSend.apply(this, arguments);};}, }; AJAX.init(); 復制代碼fetch
const FETCH = {backup: window.fetch,init() {window.fetch = function (url, conf) {return (FETCH.backup.apply(this, arguments).then((res) => {if (!res.status || res.status >= 400) {// 錯誤收集}return res;}));};}, }; FETCH.init(); 復制代碼待實現功能
參考文章
- 前端代碼異常監控實戰
- Js error 監控
- 前端一站式異常捕獲方案(全)
轉載于:https://juejin.im/post/5bd2dbc7f265da0af16183f8
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的前端错误日志收集方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018.10.29-2018.11.4
- 下一篇: HTML5中本地储存概念是什么,什么优点