一、代码执行的错误捕获1.try......catch
1.使用try... catch包裹,影响代码可读性。无法处理异步中的错误无法处理语法错误
try{
//可能出现异常的代码
}catch(异常类型 变量名){
//处理异常的代码
}finally{
//无论try块中是否有异常,均实现的代码
}
2.window.onerrorwindow.onerror
比try catch要强那么一丢丢。无论是异步还是非异步错误,onerror都能捕获到运行时错误
缺点:监听不到资源加载的报错onerror,事件处理函数只能声明—次,不会重复执行多个回调:
window.onerror是一个全局变量,默认值为null。当有js运行时错误触发时,window会触发error事件,并执行window.onerror()。onerror可以接受多个参数。
window.onerror = function(message, source, lineno, colno, error) { ... }
函数参数:
* message:错误信息(字符串)。可用于HTML onerror=""处理程序中的event。
* source:发生错误的脚本URL(字符串)
* lineno:发生错误的行号(数字)
* colno:发生错误的列号(数字)
* error:Error对象
若该函数返回true,则阻止执行默认事件处理函数,如异常信息不会在console中打印。没有返回值或者返回值为false的时候,异常信息会在console中打印
3.window.addEventListener('error')
可以监听到资源加载报错,也可以注册多个事件处理函数。
监听js运行时错误事件,会比window.onerror先触发,与onerror的功能大体类似,不过事件回调函数传参只有一个保存所有错误信息的参数,不能阻止默认事件处理函数的执行,但可以全局捕获资源加载异常的错误
window.addEventListener('error', function(event) { ... })
当资源(如img或script)加载失败,加载资源的元素会触发一个Event接口的error事件,并执行该元素上的onerror()处理函数。这些error事件不会向上冒泡到window,但可以在捕获阶段被捕获
因此如果要全局监听资源加载错误,需要在捕获阶段捕获事件
//图片加载失败使用默认图片,依旧加载失败超过三次使用base64图片
window.addEventListener('error',function(e){
let target = e.target, // 当前dom节点
tagName = target.tagName,
count = Number(target.dataset.count ) || 0, // 以失败的次数,默认为0
max= 3; // 总失败次数,此时设定为3
// 当前异常是由图片加载异常引起的
if( tagName.toUpperCase() === 'IMG' ){
if(count >= max){
target.src = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD//AK3/ALYH+5hX6FV5N4Y/5GHwx/vyf+iJa9ZrysPhoYVShDZu/potDmwWFhhIzhT2bv6aLQ//Z';
}else{
target.dataset.count = count + 1;
target.src = '//xxx/default.jpg';
}
}
},true)
4.window.addEventListener("'unhandledrejection')
捕获未处理的promise异常与错误
使用Promise编写异步代码时,使用reject来处理错误。有时,开发者通常会忽略这一点,导致一些错误没有得到处理。例如:
function main() {
asyncFunc()
.then(···)
.then(() => console.log('Done!'));
}
由于没有使用catch方法捕获错误,当asyncFunc()函数reject时,抛出的错误则没有被处理。
浏览器中未处理的Promise错误
一些浏览器(例如Chrome)能够捕获未处理的Promise错误。
。unhandledrejection
监听unhandledrejection事件,即可捕获到未处理的Promise错误:
。reason: Promise的reject值
window.addEventListener('unhandledrejection', event => {
console.log(event.reason); // Hello, Fundebug!
});
function foo() {
Promise.reject('Hello, Fundebug!');
}
foo();
当一个Promise错误最初未被处理,但是稍后又得到了处理,则会触发rejectionhandled事件
window.addEventListener('unhandledrejection', event =>
{
console.log(event.reason); // 打印"Unhandle Promise Error!"
});
window.addEventListener('rejectionhandled', event => {
console.log('rejection handled'); // 1秒后打印"rejection handled"
});
function foo() {
return Promise.reject('Unhandle Promise Error!');
}
var r = foo();
setTimeout(() => {
r.catch(e =>{});
}, 1000);
二、资源加载的错误捕获
1. imgObj.onerror()
大家上网的时候肯定见到过加载失败的红叉图片,具体如下图。当然现在Google Chrome与Firefox对其处理会好看一些。
image其实可以利用<img>图片标签的onerror事件对其处理的,要求其加载失败之后,马上加载一张默认图片,而不是显示为红叉叉。
其代码如下:
<img src="s.png" onerror="javascript:this.src='xx.png';this.width=80;this.height=80;" />
意为,如果加载s.png这张图片失败了,就马上去加载xx.png这张图片,同时xx.png这张图片要求其以80x80的方式加载。
2. performance.getEntries),获取到成功加载的资源,对比可以间接的捕获错误
浏览器获取网页时,会对网页中每一个对象(脚本文件、样式表、图片文件等等)发出一个HTTP请求。而通过window.performance.getEntries方法,则可以以数组形式,返回这些请求的时间统计信息,每个数组成员均是一个PerformanceResourceTiming对象!
用它小玩儿一下,统计页面上的静态资源加载耗时:
(function () {
// 浏览器不支持,就算了!
if (!window.performance && !window.performance.getEntries) {
return false;
}
var result = [];
// 获取当前页面所有请求对应的PerformanceResourceTiming对象进行分析
window.performance.getEntries().forEach(function (perf) {
result.push({
'url': perf.name,
'entryType': perf.entryType,
'type': perf.initiatorType,
'duration(ms)': perf.duration
});
});
// 控制台输出统计结果
console.table(result);
})();
image.png
- window.addEventListener('error', fn, true),会捕获但是不冒泡,所以window.onerror不会触发,捕获阶段可以触发 上面已经有示例代码
三、错误上报
—般使用image来上报,用请求图片的方式来上报信息问题;
使用图片发送get请求,上报信息,由于浏览器对图片有缓存,同样的请求,图片只会发送一次,避免重复上报。
例: 和请求ajax的方式一样
<script>
(new Image()).src="http://www.baidu.com?n=fff"
</script>
首先创建一个图片,将其src属性设置为
http://www.baidu.com?n=fff
后期的参数就是需要上报的错误了,可以直接在network中查看参数,类似于ajax请求.
image.png
四、借助第三方库
o sentry-javascript
网友评论