您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關前端一站式異常監控的捕獲方案是怎樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一、前端異常監控的重要性
軟件異常監控常常直接關聯到軟件本身的質量,完備的異常監控體系常常能夠快速定位到軟件運行中發生的問題,并能幫助我們快速定位異常的源頭,提升軟件質量。
在服務器開發中,我們常常使用日志來記錄請求的錯誤和服務器異常問題,但是在客戶端,前端應用直接部署運行在用戶的瀏覽器中,如果發生錯誤,應該怎樣去捕獲并傳送給服務器呢?前端錯誤日志傳送給服務器很簡單,在異常發生時直接發請求就可以了,下面我們主要討論下錯誤的捕獲方案。
二、現有的異常監控方案
window.onerror全局異常捕獲   目前前端捕獲頁面異常的方式主要有兩種,window.onerror捕獲整個頁面中運行的錯誤,它的局限是對于跨域的JavaScript腳本需要添加跨域支持,也就是需要涉及服務器的修改成本,否則無法獲取到運行時具體的堆棧錯誤信息,而是"script error"的信息,不利于我們定位問題。
window.onerror = function(msg, file, row, column, errorObj) { console.log(msg); // script error. console.log(file); // console.log(row); // 0 console.log(column); // 0 console.log(errorObj); // {} setTimeout(function() { // 發送請求上報日志信息 errorReport(e.name, e.message + e.stack); }, 5000); }
<script src="//domain.com/path/main.js" crossorigin></script>
try-catch運行時解決方案
  現有的另一中方案則是try-catch,對于某個方法函數,我們可以這樣定義來捕獲函數里面運行時的異常,但是try-catch只能捕獲當前單個作用域下的異常。另外,使用try-catch會帶來一定的性能損耗,根據循環測試,平均大概會損失6%~10%的性能,但是為了提升應用的質量和穩定性,這些是可以接受的。
function wrapFunction(fn) { return function() { try { return fn.apply(this, arguments); } catch (e) { console.log(e); _errorProcess(e); return; } }; } // 之后fn函數里面的代碼運行出錯時則是可以被捕獲到的了 fn = wrapFunction(fn); // 或者異步函數里面的回調函數中的錯誤也可以被捕獲到 var _setTimeout = setTimeout; setTimeout = function(fn, time){ return _setTimeout(wrapFunction(fn), time); } // 模塊定義函數也可以做重寫定義 var _require = require; require = function(id, deps, factory) { if (typeof(factory) !== 'function' || !factory) { return _require(id, deps); } else { return _require(id, deps, wrapFunction(factory)); } };
那么我們可以對常用的模塊入口函數進行重定義,包括define,require等,這樣模塊中的主要作用域中的異常都可以通過try-catch來捕獲了。在之前的處理方法中,這種方法是非常有效的,直接可以拿到大多數錯誤棧中的異常和堆棧信息。
三、改進的一站式解決方案
React開發時代,這種方式就不能直接使用了,我們知道React的組件都是class,其實也就是構造函數,這里普及下class和構造函數其實是非常類似的,class A除了constructor為class A,其它信息和function A類似,typeof獲取的類型也相同。但是我們是沒辦法把構造函數A直接裝入try-catch中運行的,因為需要通過關鍵字new進行實例化,并創建新的作用域。
此時我們要處理的問題其實是捕獲React中屬性方法中的錯誤,應該還記得,JavaScript中函數有個特殊的屬性prototype,當函數作為構造函數是,prototype中的屬性就成了實例化后的屬性方法,而且這一屬性對class同樣生效。那么我們可以對React中class的prototype這個特殊屬性的內容進行處理,對Component中的方法函數進行封裝。
function defineReact(Component) { var proto = Component.prototype; for (var key in proto) { if (typeof(proto[key]) === 'function') { proto[key] = _wrapFunction(proto[key]); } } return Component; }
這樣通過實例化產生的React組件中的內部方法中的錯誤就可以被捕獲到了。
class component extends React.Component { componentDidMount(){ var a = {}; console.log(a.b.c); } render() { return <div>hello world</div>; } } export default defineReact(component);
這里添加defineReact的操作就可以放到構建打包工具中去處理了,這樣就避免了我們對代碼層直接進行修改。
React直接報錯不利于定位問題
封裝后直接獲取堆棧錯誤
四、小結
其實和原有的方式差別不大,仍然通過try-catch的方式,覆蓋到React組件prototype屬性中進行異常捕獲,極大增加了錯誤捕獲范圍,不僅能幫助我們快速定位開發中的問題,也能捕獲React線上應用的運行時錯誤。
上述就是小編為大家分享的前端一站式異常監控的捕獲方案是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。