一沸久、為什么要處理異常季俩?
1 增強(qiáng)用戶體驗(yàn)
2 遠(yuǎn)程定位問題
3 未雨綢繆 發(fā)現(xiàn)問題
4 無法浮現(xiàn)問題 尤其是移動(dòng)端 機(jī)型 系統(tǒng)都是問題
5 完善的前端方案 前端監(jiān)控系統(tǒng)
二挡鞍、需要處理哪些異常
1法褥、js預(yù)發(fā)錯(cuò)誤 代碼異常
2卖氨、ajax請求異常
3、靜態(tài)資源家在異常
4残炮、promise異常
5韭赘、iframe異常
6、跨域script error
7势就、崩潰和卡頓
Try-Catch的誤區(qū)
try-catch只能捕獲同步的運(yùn)行時(shí)錯(cuò)誤泉瞻。對語法和異步的錯(cuò)誤無能為力脉漏,捕獲不到。
1袖牙、同步運(yùn)行時(shí)錯(cuò)誤
2侧巨、不能捕獲具體的語法錯(cuò)誤,只有一個(gè)語法錯(cuò)誤提示
3鞭达、異步錯(cuò)誤
異步異常 捕獲不到
四司忱、window.onerror不是萬能的
當(dāng)js運(yùn)行時(shí)錯(cuò)誤發(fā)生時(shí),window會(huì)觸發(fā)一個(gè)ErrorEvent接口的error事件畴蹭,并執(zhí)行window.onerror
/**
message: 錯(cuò)誤信息
source: 出錯(cuò)文件
lineno: 行號
error: 錯(cuò)誤對象
*/
window.onerror = function(message, source, lineno, colno, error){
console.log('異常捕獲', {message, source, lineno, colno, error})
}
1坦仍、同步信息錯(cuò)誤
2、語法錯(cuò)誤
3叨襟、模擬異步運(yùn)行時(shí)的錯(cuò)誤
setTimeout(() => {
michael
}, 3000)
補(bǔ)充一點(diǎn):window.onerror 函數(shù)只有返回true的時(shí)候繁扎,異常才不會(huì)向上拋出,否則控制臺(tái)還是會(huì)顯示Uncaught Error: XXXXXXXX
注意:
onerror最好寫在所有的js腳本的前面糊闽,否則有可能捕獲不到錯(cuò)誤梳玫。
onerror無法捕獲語法錯(cuò)誤
五、winodw.addEventListener 靜態(tài)資源加載異常
當(dāng)資源加載失敗右犹,加載資源的元素會(huì)觸發(fā)一個(gè)Event接口的error事件提澎,并執(zhí)行該元素上的onerror處理函數(shù)
window.addEventListener('error', function(error){
console.log('捕獲到異常',error)
}, true)
六傀履、Promise Catch
primise中使用catch可以獲取到異步的error, 但是如果忘了怎么辦
解決方案:為了防止有漏掉的Promise異常虱朵,建議在全局增加一個(gè)對unhandlerejection的監(jiān)聽莉炉,用來全局監(jiān)聽 Uncaught Promise Error
window.addEventListener('unhandledrejection', function(e) {
e.preventDefault()
console.log(e)
return true
})
Promise.reject('error')
七钓账、vue errorHandler
Vue.config.errorHandler = (err, vm, info) => {
console.error('通過vue errorHandler捕獲的錯(cuò)誤');
console.error(err);
console.error(vm);
console.error(info);
}
八、react中異常捕獲
componentDidCatch(error, info){
}
注意點(diǎn):error boundaries并不會(huì)捕獲下面錯(cuò)誤
1絮宁、事件處理器
2梆暮、異步代碼
3、服務(wù)端的渲染代碼
4绍昂、在error boundaries區(qū)域內(nèi)的錯(cuò)誤
九啦粹、iframe異常
<iframe src="./frame.html"></iframe>
window.frames[0].onerror = function(message, source, lineno, colno, error){
console.log('異常', { message, source, lineno, colno, error })
return true
}
十、Script error
基本上跨域問題
十一窘游、崩潰和卡頓
利用window對象的load和beforeunload事件實(shí)現(xiàn)了網(wǎng)頁崩潰的監(jiān)控唠椭。
window.addEventListener('load', function(){
sessionStorage.setItem('good_exit', 'pending')
setInterval(function(){
sessionStorage.setItem('time_before', new Date().toString())
}, 1000)
})
window.addEventListener('beforeunload', function(){
sessionStorage.setItem('good_exit', 'true')
})
if(sessionStorage.getItem('good_exit') && sessionStorage.getItem('good_exit') !== 'true'){
alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'))
}
2、基于以下原因忍饰,我們可以使用 Service Worker 來實(shí)現(xiàn)網(wǎng)頁崩潰的監(jiān)控:
Service Worker 有自己獨(dú)立的工作線程贪嫂,與網(wǎng)頁區(qū)分開,網(wǎng)頁崩潰了艾蓝,Service Worker 一般情況下不會(huì)崩潰力崇;Service Worker 生命周期一般要比網(wǎng)頁還要長斗塘,可以用來監(jiān)控網(wǎng)頁的狀態(tài);網(wǎng)頁可以通過 navigator.serviceWorker.controller.postMessage API 向掌管自己的 SW 發(fā)送消息亮靴。
知乎上關(guān)于service work來監(jiān)控的方案
十二 錯(cuò)誤上報(bào)
1馍盟、通過ajax 風(fēng)險(xiǎn):ajax本身也有報(bào)錯(cuò)風(fēng)險(xiǎn),跨域問題
2茧吊、動(dòng)態(tài)創(chuàng)建img標(biāo)簽的形式
function report(error){
let url = 'http://www.baicuu.com'
new Image().src = `${url}?logs=${error}`
}
收集信息太多怎么辦贞岭?如何減少服務(wù)器的壓力
Report.send = function(data){
if(Math.random < 0.3) {
send(data)
}
}
視情況定,用戶特征等等
十三 總結(jié)
如何優(yōu)雅的處理異常
1搓侄、可疑區(qū)增加try-catch
2曹步、全局監(jiān)控js異常
3、全局監(jiān)控靜態(tài)資源異常 window.addEventListener
4休讳、
5讲婚、
6、監(jiān)控網(wǎng)頁崩潰:window對象的load 和 beforeunload
7俊柔、跨域crossOrigin
分類型解決異常