html视频资源加载出错处理,如何处理前端异常
錯(cuò)誤類型數(shù)據(jù)
錯(cuò)誤類型主要是運(yùn)行過程中的前端報(bào)錯(cuò),Javascript原生提供Error構(gòu)造函數(shù),所有拋出的錯(cuò)誤都是它的實(shí)例。Error實(shí)例對(duì)象有以下屬性屬性描述message錯(cuò)誤提示信息
name錯(cuò)誤名稱
stack錯(cuò)誤的棧
異常情況
總的來說其實(shí)可以分很多種,輕則影響局部流程問題,嚴(yán)重的會(huì)影響頁面崩潰甚至白屏SyntaxError: 語法錯(cuò)誤
TypeError: 類型錯(cuò)誤
RangeError: 范圍錯(cuò)誤
ReferenceError: 引用錯(cuò)誤
EvalError: eval錯(cuò)誤
URIError: URL錯(cuò)誤
AggregateError: 多個(gè)錯(cuò)誤(實(shí)驗(yàn)中的功能)
Failed to load resource: 資源加載錯(cuò)誤
SyntaxError
當(dāng)Javascript語言解析代碼時(shí),Javascript引擎發(fā)現(xiàn)了不符合語法規(guī)范的tokens或token順序時(shí)拋出SyntaxError.
也可以手動(dòng)拋出,語法如下new SyntaxError([message[, fileName[, lineNumber]]])
TypeError
當(dāng)傳入函數(shù)的操作數(shù)或參數(shù)的類型并非操作符或函數(shù)所預(yù)期的類型時(shí),將拋出一個(gè) TypeError 類型錯(cuò)誤。
也可以手動(dòng)拋出,語法如下new TypeError([message[, fileName[, lineNumber]]])
RangeError
試圖傳遞一個(gè)number參數(shù)給一個(gè)范圍內(nèi)不包含該number的函數(shù)時(shí)則會(huì)引發(fā)RangeError。當(dāng)傳遞一個(gè)不合法的length值作為 Array 構(gòu)造器的參數(shù)創(chuàng)建數(shù)組,或者傳遞錯(cuò)誤值到數(shù)值計(jì)算方法(Number.toExponential(),Number.toFixed() ,Number.toPrecision()),會(huì)出現(xiàn)RangeError。.
也可以手動(dòng)拋出,語法如下new RangeError([message[, fileName[, lineNumber]]])
ReferenceError
當(dāng)你嘗試引用一個(gè)未被定義的變量時(shí),將會(huì)拋出一個(gè) ReferenceError 。
也可以手動(dòng)拋出,語法如下new ReferenceError([message[, fileName[, lineNumber]]])
EvalError
本對(duì)象代表了一個(gè)關(guān)于 eval 函數(shù)的錯(cuò)誤.此異常不再會(huì)被JavaScript拋出,但是EvalError對(duì)象仍然保持兼容性.
也可以手動(dòng)拋出,語法如下new EvalError([message[, fileName[, lineNumber]]])
URIError
當(dāng)向全局 URI 處理函數(shù)傳遞一個(gè)不合法的URI時(shí),URIError 錯(cuò)誤會(huì)被拋出。
也可以手動(dòng)拋出,語法如下new URIError([message[, fileName[, lineNumber]]])
AggregateError
一個(gè)AggregateError當(dāng)需要由操作報(bào)告多個(gè)錯(cuò)誤被拋出,例如通過Promise.any(),在傳遞給它的所有Promise拒絕。
也可以手動(dòng)拋出,語法如下new AggregateError(errors[, message])
Failed to load resource
以下標(biāo)簽加載資源出錯(cuò) , , ,
可以通過onerror或者全局監(jiān)聽error事件捕獲,下文會(huì)提到
我們排除掉資源和語法等不可控的因素,從代碼角度分析有哪些可以協(xié)助我們開發(fā)提高代碼的健壯性.
Try-Catch
這種方式適用于你知道這段代碼可能會(huì)出現(xiàn)異常或者當(dāng)做代碼出現(xiàn)異常的后備處理方式
try 語句測(cè)試代碼塊的錯(cuò)誤。
catch 語句處理錯(cuò)誤。
throw 語句創(chuàng)建自定義錯(cuò)誤。
finally 語句在 try 和 catch 語句之后,無論是否有觸發(fā)異常,該語句都會(huì)執(zhí)行。
1, 僅支持捕獲同步異常try {
console.log(a)
} catch (error) {
console.log('a is not defined')
} finally {
console.log('always')
}
// a is not defined
// always
2, 不能用于捕獲異步異常try {
setTimeout(() => {
console.log(a)
}, 1000)
} catch (e) {
console.log('捕獲到異常:', e);
}
// ReferenceError: a is not defined
3, 語法錯(cuò)誤不在其可捕獲范圍try {
str = '
} catch (e) {
console.log('捕獲到異常:', e);
}
// SyntaxError: Invalid or unexpected token
Promise Catch
promise catch和try-catch的區(qū)別其實(shí)也跟回調(diào)函數(shù)和Promise的關(guān)系有淵源,前者也可用于捕獲異步編程異常,后者僅支持同步流程
1, 同步異常捕獲new Promise(resolve => {
resolve(a)
}).catch (err => {
console.log('catch: ', err)
})
// catch: ReferenceError: a is not defined
2, 異步異常捕獲new Promise(resolve => {
setTimeout(() => {
resolve(a)
}, 1000)
}).catch(err => {
console.log('catch: ', err)
})
// ReferenceError: a is not defined
3, 同樣不能捕獲語法錯(cuò)誤new Promise(resolve => {
setTimeout(() => {
str = '
resolve()
}, 1000)
}).catch(err => {
console.log('catch: ', err)
})
// SyntaxError: Invalid or unexpected token
React && Vue 捕獲API
依賴框架所提供的API,功能強(qiáng)大,但是也有版本兼容的問題
Vue errorHandlerVue.config.errorHandler = function (err, vm, info) {
// handle error
// `info` 是 Vue 特定的錯(cuò)誤信息,比如錯(cuò)誤所在的生命周期鉤子
// 只在 2.2.0+ 可用
}
指定組件的渲染和觀察期間未捕獲錯(cuò)誤的處理函數(shù)。這個(gè)處理函數(shù)被調(diào)用時(shí),可獲取錯(cuò)誤信息和 Vue 實(shí)例從 2.2.0 起,這個(gè)鉤子也會(huì)捕獲組件生命周期鉤子里的錯(cuò)誤。同樣的,當(dāng)這個(gè)鉤子是 undefined 時(shí),被捕獲的錯(cuò)誤會(huì)通過 console.error 輸出而避免應(yīng)用崩潰。
從 2.4.0 起,這個(gè)鉤子也會(huì)捕獲 Vue 自定義事件處理函數(shù)內(nèi)部的錯(cuò)誤了。
從 2.6.0 起,這個(gè)鉤子也會(huì)捕獲 v-on DOM 監(jiān)聽器內(nèi)部拋出的錯(cuò)誤。另外,如果任何被覆蓋的鉤子或處理函數(shù)返回一個(gè) Promise 鏈 (例如 async 函數(shù)),則來自其 Promise 鏈的錯(cuò)誤也會(huì)被處理。
React componentDidCatch
這個(gè)沒用過,貼上官網(wǎng)給你們自己看.
部分 UI 的 JavaScript 錯(cuò)誤不應(yīng)該導(dǎo)致整個(gè)應(yīng)用崩潰,為了解決這個(gè)問題,React 16 引入了一個(gè)新的概念 —— 錯(cuò)誤邊界。
錯(cuò)誤邊界是一種 React 組件,這種組件可以捕獲并打印發(fā)生在其子組件樹任何位置的 JavaScript 錯(cuò)誤,并且,它會(huì)渲染出備用 UI,而不是渲染那些崩潰了的子組件樹。錯(cuò)誤邊界在渲染期間、生命周期方法和整個(gè)組件樹的構(gòu)造函數(shù)中捕獲錯(cuò)誤。
注意
錯(cuò)誤邊界無法捕獲以下場(chǎng)景中產(chǎn)生的錯(cuò)誤:事件處理
異步代碼(例如 setTimeout 或 requestAnimationFrame 回調(diào)函數(shù))
服務(wù)端渲染
它自身拋出來的錯(cuò)誤(并非它的子組件)
如果一個(gè) class 組件中定義了 static getDerivedStateFromError() 或 componentDidCatch() 這兩個(gè)生命周期方法中的任意一個(gè)(或兩個(gè))時(shí),那么它就變成一個(gè)錯(cuò)誤邊界。當(dāng)拋出錯(cuò)誤后,請(qǐng)使用 static getDerivedStateFromError() 渲染備用 UI ,使用 componentDidCatch() 打印錯(cuò)誤信息。class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// 更新 state 使下一次渲染能夠顯示降級(jí)后的 UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// 你同樣可以將錯(cuò)誤日志上報(bào)給服務(wù)器
logErrorToMyService(error, errorInfo);
}
render() {
if (this.state.hasError) {
// 你可以自定義降級(jí)后的 UI 并渲染
return
Something went wrong.
;}
return this.props.children;
}
}
錯(cuò)誤邊界的工作方式類似于 JavaScript 的 catch {},不同的地方在于錯(cuò)誤邊界只針對(duì) React 組件。只有 class 組件才可以成為錯(cuò)誤邊界組件。大多數(shù)情況下, 你只需要聲明一次錯(cuò)誤邊界組件, 并在整個(gè)應(yīng)用中使用它。
注意錯(cuò)誤邊界僅可以捕獲其子組件的錯(cuò)誤,它無法捕獲其自身的錯(cuò)誤。如果一個(gè)錯(cuò)誤邊界無法渲染錯(cuò)誤信息,則錯(cuò)誤會(huì)冒泡至最近的上層錯(cuò)誤邊界,這也類似于 JavaScript 中 catch {} 的工作機(jī)制。
window.onerror
相比于try-catch捕獲可預(yù)知代碼塊,window.onerror用于全局捕獲錯(cuò)誤,當(dāng)JavaScript運(yùn)行時(shí)錯(cuò)誤(包括語法錯(cuò)誤)發(fā)生時(shí),window會(huì)觸發(fā)一個(gè)ErrorEvent接口的error事件,并執(zhí)行window.onerror()。
當(dāng)一項(xiàng)資源(如或
函數(shù)參數(shù):message:錯(cuò)誤信息(字符串)。可用于HTML οnerrοr=""處理程序中的event。
source:發(fā)生錯(cuò)誤的腳本URL(字符串)
lineno:發(fā)生錯(cuò)誤的行號(hào)(數(shù)字)
colno:發(fā)生錯(cuò)誤的列號(hào)(數(shù)字)
error:Error對(duì)象(對(duì)象)
若該函數(shù)返回true,則阻止執(zhí)行默認(rèn)事件處理函數(shù)。
1, 同步異常捕獲window.onerror = function(message, source, lineno, colno, error) {
console.log('捕獲到異常:',{message, source, lineno, colno, error});
}
2, 異步異常捕獲window.onerror = function(message, source, lineno, colno, error) {
console.log('捕獲到異常:',{message, source, lineno, colno, error});
}
new Promise(resolve => {
setTimeout(() => {
resolve(a)
}, 1000)
}).catch(err => {
console.log('catch: ', err)
})
3, 同樣不能捕獲語法錯(cuò)誤window.onerror = function(message, source, lineno, colno, error) {
console.log('捕獲到異常:',{message, source, lineno, colno, error});
}
str = '
// Uncaught SyntaxError: Invalid or unexpected token
window.addEventListener
和window.onerror類似,只是捕獲的參數(shù)不同,并且window.addEventListener還可以捕獲到資源加載失敗的異常window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
1, 同步異常捕獲window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
a
2, 異步異常捕獲window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
new Promise(resolve => {
setTimeout(() => {
resolve(a)
}, 1000)
}).catch(err => {
console.log('catch: ', err)
})
3, 同樣不能捕獲語法錯(cuò)誤window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
str = '
// Uncaught SyntaxError: Invalid or unexpected token
4, 資源加載失敗
window.addEventListener('error', (error) => {
console.log('捕獲到異常:', error);
}, true)
總結(jié)
以上是生活随笔為你收集整理的html视频资源加载出错处理,如何处理前端异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 改python,如何正确
- 下一篇: 华为 鸿蒙只是物联网,“鸿蒙”不只是手机