這種方案要求開發人員在編寫代碼的時候,在預估有異常發生的代碼段使用try...catch
,在發生異常時將異常信息發送給接口:瀏覽器
可是 try-catch 處理異常的能力有限,只能捕獲捉到運行時非異步錯誤,對於語法錯誤和異步錯誤就顯得無能爲力,捕捉不到。網絡
try{ //可能發生異常的代碼段 }catch(e){ //將異常信息發送服務端 }
try...catch
的優勢是能夠細化到每一個代碼塊,而且能夠自定義錯誤信息以便統計。異步
具體到上文提到的兩種js異常,try...catch
沒法捕獲語法錯誤,當遇到語法錯誤時,瀏覽器仍然會拋出錯誤Uncaught SyntaxError
,可是不會被捕獲,不會走進catch的代碼塊內。函數
另外,若是try代碼塊中有回調函數也不會被捕獲,好比:工具
try{ var btn = $('#btn'); btn.on('click',function(){ //throw error }); }catch(e){}
上述代碼中btn的監聽函數裏拋出的異常沒法被外層的catch捕獲到,必須額外套一層:spa
try{ var btn = $('#btn'); btn.on('click',function(){ try{ //throw error }catch(e){} }); }catch(e){}
綜上所述,try...catch
方案的部署很是複雜,若是人工部署除了要求巨量的工做量,還跟開發人員的能力和經驗有關。若是依賴編譯工具部署(好比fis),那每一個代碼塊都套一層try...catch
也是很是難看的而且容易引起一些不可預估的問題。日誌
window.onerror 捕獲異常能力比 try-catch 稍微強點,不管是異步仍是非異步錯誤,onerror 都能捕獲到運行時錯誤。code
這種方式不須要開發人員在代碼中書寫大量的try...catch
,經過給window添加onerror監聽,在js發生異常的時候即可以捕獲到錯誤信息,語法異常和運行異常都可被捕獲到。blog
可是window.onerror
這個監聽必須放在全部js文件以前才能夠保證可以捕獲到全部的異常信息。接口
window.onerror 函數只有在返回 true 的時候,異常纔不會向上拋出,不然即便是知道異常的發生控制檯仍是會顯示 Uncaught Error: xxxxx。
對於 onerror 這種全局捕獲,最好寫在全部 JS 腳本的前面,由於你沒法保證你寫的代碼是否出錯,若是寫在後面,一旦發生錯誤的話是不會被 onerror 捕獲到的。
另外 onerror 是沒法捕獲到網絡異常的錯誤。
window.onerror
事件的詳細信息參考這裏。
/** * @param {String} errorMessage 錯誤信息 * @param {String} scriptURL 出錯文件的URL * @param {Long} lineNumber 出錯代碼的行號 * @param {Long} columnNumber 出錯代碼的列號 * @param {Object} errorObj 錯誤信息Object */ window.onerror = function(errorMessage, scriptURL, lineNumber,columnNumber,errorObj) { // code.. }
下圖是被onerror捕獲到的一個異常的具體信息:
綜上所述,window.onerror
方案的優勢是減小了開發人員的工做量,部署方便,而且能夠捕獲語法錯誤和運行錯誤。
缺點是錯誤信息不能自定義,而且errorObj每種瀏覽器的實現有略微差別,致使需統計的信息有侷限性。