异常分类
微信图片_20201208174539.png
捕获异常技巧
1.可疑区域增加 try...catch(只能捕获到同步的运行时错误,对于语法和异步错误无能为力,捕获不到。)
例:
try {
let name = 'Jack';
console.log(nam);
} catch(e) {
console.log('捕获到异常:',e);
}
输出:
捕获到异常:ReferenceError: nam is not defined
at <anonymous>:3:15
2.全局监控JS异常: window.onerror(不是万能的,只有在返回 true 的时候,异常才不会向上抛出(浏览器接收后报红),否则即使是知道异常的发生控制台还是会显示 Uncaught Error: xxxxx,最好写在所有JS脚本的前面,否则有可能捕获不到错误,无法捕获语法错误)
window.onerror = function(message, source, lineno, colno, error) {
// message:错误信息(字符串)。
// source:发生错误的脚本URL(字符串)
// lineno:发生错误的行号(数字)
// colno:发生错误的列号(数字)
// error:Error对象(对象)
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
3.全局监控静态资源异常: window.addEventListener
<script>
window.addEventListener('error', (error) => {
console.log('捕获到异常:', error);
}, true)
</script>
<img src="./xxxx.png">
4.全局捕获没有 catch 的 promise 异常:unhandledrejection
window.addEventListener("unhandledrejection", function(e){
// e.preventDefault(); // 阻止异常向上抛出
console.log('捕获到异常:', e);
});
Promise.reject('promise error');
5.iframe 异常:window.onerror
例:
<iframe src="./iframe.html" frameborder="0"></iframe>
<script>
window.frames[0].onerror = function (message, source, lineno, colno, error) {
console.log('捕获到 iframe 异常:', {message, source, lineno, colno, error});
};
</script>
6.VUE errorHandler 和 React componentDidCatch
Vue
Vue.config.errorHandler = function (err, vm, info) {
let {
message, // 异常信息
name, // 异常名称
script, // 异常脚本url
line, // 异常行号
column, // 异常列号
stack // 异常堆栈信息
} = err;
// vm为抛出异常的 Vue 实例
// info为 Vue 特定的错误信息,比如错误所在的生命周期钩子
}
React
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
7.监控网页崩溃:window 对象的 load 和 beforeunload
window.addEventListener('load', function () {
sessionStorage.setItem('good_exit', 'pending');
setInterval(function () {
sessionStorage.setItem('time_before_crash', new Date().toString());
}, 1000);
});
window.addEventListener('beforeunload', function () {
sessionStorage.setItem('good_exit', 'true');
});
if(sessionStorage.getItem('good_exit') &&
sessionStorage.getItem('good_exit') !== 'true') {
/*
insert crash logging code here
*/
alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash'));
}
8.Script Error跨域 crossOrigin 解决(跨源资源共享机制( CORS ):我们为 script 标签添加 crossOrigin 属性)
<script src="http://jartto.wang/main.js" crossorigin></script>