错误类型:
常见JS执行错误:
- SyntaxError:语法错误,解析时发生语法错误
// 在控制台运行 // 一般语法错误 const xx, // 特殊语法错误 JSON.parse('');
- SyntaxError在构建阶段,甚至本地开发阶段就会被发现;
- 而特殊语法错误可以被所有错误捕获方式捕获。
- TypeError:类型错误,值不是所期待的类型
// 控制台运行 const person = undefined; person.name;
- ReferenceError:引用错误,引用未声明的变量
// 控制台运行 nodefined;
- RangeError:范围错误,当一个值不在其所允许的范围或者集合中
// 控制台运行 // 爆栈 (function fn() { fn(); })();
网络错误:
- ResourceError:资源加载错误
// 控制台运行 new Image().src = '/remote/image/notdeinfed.png';
- HttpError:http请求错误
// 控制台运行 fetch('/remote/notdefined');
错误捕获:
try/catch:
能捕获常规的运行时错误,但是语法错误和异步错误不行。
// 一般语法错误 ❌
try {
const xx,
} catch (error) {
console.log('一般语法错误: ', error);
}
// 特殊语法错误 ✅
try {
JSON.parse('');
} catch (error) {
console.log('特殊语法错误: ', error);
}
// 类型错误 ✅
try {
const person = undefined;
person.name;
} catch (error) {
console.log('类型错误: ', error);
}
// 引用错误 ✅
try {
a;
} catch (error) {
console.log('引用错误: ', error);
}
// 范围错误 ✅
try {
(function fn() {
fn();
})();
} catch (error) {
console.log('范围错误: ', error);
}
// 下面都属于异步错误:
// 资源加载错误 ❌
try {
new Image().src = 'aaa';
} catch (error) {
console.log('资源加载错误: ', error);
}
// http请求错误 ❌
try {
fetch('aaa');
} catch (error) {
console.log('http请求错误: ', error);
}
// promise异步错误 ❌
try {
new Promise(() => {
a;
});
} catch (error) {
console.log('promise异步错误: ', error);
}
// setTimeout/setInterval异步错误 ❌
try {
setTimeout(() => {
b;
}, 0);
} catch (error) {
console.log('setTimeout/setInterval异步错误: ', error);
}
window.onerror
当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件。
/**
* @param {String} message 错误信息
* @param {String} source 出错文件
* @param {Number} lineno 行号
* @param {Number} colno 列号
* @param {Object} error Error对象
*/
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:', {message, source, lineno, colno, error});
};
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:', {message, source, lineno, colno, error});
};
window.onload = function () {
// 一般语法错误 ❌
const xx,
// 特殊语法错误 ✅
JSON.parse('');
// 类型错误 ✅
const person = undefined;
person.name;
// 引用错误 ✅
a;
// 范围错误 ✅
(function fn() {
fn();
})();
// 资源加载错误 ❌
new Image().src = 'aaa';
// http请求错误 ❌
fetch('aaa');
// promise异步错误 ❌
new Promise(() => {
a;
});
// setTimeout/setInterval异步错误 ✅
setTimeout(() => {
b;
}, 0);
};
window.onerror不能捕获语法错误和promise异步错误(包括网络错误)。
window.addEventListener('error', fn, true);
当一项资源(如图片或脚本)加载失败,加载资源的元素会触发一个 Event 接口的 error 事件,这些 error 事件不会向上冒泡到 window,但能被捕获。而window.onerror不能监测捕获。
window.addEventListener('error', fn)
对于js的错误检测和window.onerror
相同。
但是window.addEventListener('error', fn, true)
可以检测出html标签资源加载错误。
window.addEventListener('error', (err) => {
console.log('捕获到异常:', err);
}, true);
const img = document.createElement('img');
img.src = 'aaa';
// 不加这行代码,会进行资源请求,但是错误不会被捕获
document.body.appendChild(img);
const script = document.createElement('script');
script.src = 'bbb';
document.body.appendChild(script);
const link = document.createElement('link');
link.href = 'ccc';
link.rel = 'stylesheet';
document.body.appendChild(link);
到目前为止,还有语法错误、promise异步错误、new Image资源加载错误还没有捕获方法。
- 语法错误可以在开发阶段依靠编辑器发现,上线的项目是不会出现语法错误的;
- new Image资源加载错误使用的较少,可以通过
img.onerror = fn
来单独处理; - promise异步错误是需要着重考虑的!
Promise异步错误:
通过unhandledrejection事件捕获;
window.addEventListener('unhandledrejection', function (ev) {
console.log('promise异步错误:', ev);
});
new Promise(() => {
a;
});
fetch('aaa');