一买雾、為什么要處理異常尼夺?
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請(qǐng)求異常
3定踱、靜態(tài)資源家在異常
4棍潘、promise異常
5、iframe異常
6崖媚、跨域script error
7亦歉、崩潰和卡頓
Try-Catch的誤區(qū)
try-catch只能捕獲同步的運(yùn)行時(shí)錯(cuò)誤。對(duì)語法和異步的錯(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: 行號(hào)
error: 錯(cuò)誤對(duì)象
*/
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è)對(duì)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對(duì)象的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對(duì)象的load 和 beforeunload
7擦耀、跨域crossOrigin
分類型解決異常