js代码运行时,希望能捕获异常错误,上报后台监控,及时修复bug,那么如何捕获错误?下面我们来看下有哪些错误。
语法错误
同步错误
window.addEventListener('error', ()=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
throw new Error();
// "addEventListener"
异步错误
window.addEventListener('error', ()=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
setTimeout(()=>{
throw new Error();
}, 10)
// "addEventListener"
资源错误(img、script、object等)
// 资源加载前,必须先监听错误事件
window.addEventListener('error', ()=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
<img src="../404.png" />
<script src="../404.png"></script>
// "addEventListener"
// "addEventListener"
console.error错误
var consoleError = window.console.error;
window.console.error = function () {
console.log('console')
consoleError && consoleError.apply(window, arguments);
};
console.error('error')
// "console"
// "error"
js跨域错误
// 跨域错误默认提示 Script error
window.addEventListener('error', ()=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
// 客户端添加crossorigin属性
// 服务端添加Access-Control-Allow-Origin: *
// 否则只提示Script error,无法获取具体错误信息
<script src="https://dss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/static/protocol/https/jquery/jquery-1.10.2.min_65682a2.js"></script>
// "addEventListener"
promise错误
window.addEventListener('error', ()=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
new Promise((resolve, reject)=>{
throw new Error();
})
new Promise((resolve, reject)=>{
resolve('')
})
.then((data)=>{
throw new Error();
})
new Promise((resolve, reject)=>{
throw new Error();
})
.catch((err)=>{
console.error(err)
})
// [object Error] { ... }
// "unhandledrejection"
// "unhandledrejection"
async/await错误
window.addEventListener('error', (e)=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
async function compute () {
let a = 1;
let b = await a + 2;
throw new Error('async error')
}
compute()
// "unhandledrejection"
genrator错误
window.addEventListener('error', (e)=>{
console.log('addEventListener')
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
// gennerator
function* F() {
throw new Error("gennerator-throw在函数体外抛出的错误")
yield 1;
return "gennerator-value";
}
var f = F();
f.next();
// "addEventListener"
iframe错误
var frames = window.frames;
for (var i = 0; i < frames.length; i++) {
frames[i].addEventListener('error', (e)=>{
console.log('addEventListener')
console.log(e)
}, true);
frames[i].addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
}, true);
}
请求错误(XMLHttpRequest、fetch)
window.addEventListener('error', (e)=>{
console.log('addEventListener')
console.log(e)
}, true);
window.addEventListener("unhandledrejection", function(e) {
console.log('unhandledrejection')
console.log(e)
}, true);
// 请求返回错误
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
// 无效请求
fetch('http://example.com/404.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=state_Change;
xmlhttp.open("GET", 'http://127.0.0.1:8000/',true);
xmlhttp.send(null);
function state_Change(){
if (xmlhttp.readyState == 4){// 4 = "loaded"
if (xmlhttp.status == 200){// 200 = "OK"
throw new Error('error')
}else{
console.log("Problem retrieving XML data:" + xmlhttp.statusText);
}
}
}
// fetch: "unhandledrejection"
// fetch: "unhandledrejection"
// xmlhttp: "addEventListener"
错误类型
Error
代码运行时的错误,除了 Error
这个对象,一些内置 错误类 在异常时返回,如SyntaxError
、 EvalError
、 RangeError
、 ReferenceError
、 TypeError
等,具体信息Error
Script error.
跨域脚本,为了防止信息泄露,不会展示语法错误具体信息,只会展示 Script error.
可以先解决跨域:
- 客户端script标签添加
crossorigin="anonymous"
- 服务端响应header添加
Access-Control-Allow-Origin: *
或者使用 try/catch
捕获运行方法的错误信息
SyntaxError
语法错误是无法被捕获的,因为语法错误脚本不会放入任务队列,不会继续执行这段脚本,所以也不会有事件冒泡,这个是要在开发阶段就要防范,但是使用 eval
执行却可以捕获到错误信息
try {
eval('hoo bar');
} catch (e) {
console.log(e instanceof SyntaxError); // true
console.log(e.message); // "missing ; before statement"
console.log(e.name); // "SyntaxError"
console.log(e.fileName); // "Scratchpad/1"
console.log(e.lineNumber); // 1
console.log(e.columnNumber); // 4
console.log(e.stack); // "@Scratchpad/1:2:3\n"
}
DOMException
Web API 访问和调用时错误,API报错会设置错误name,如 SyntaxError
、 NotFoundError
等,具体信息DOMException
错误事件
error
window.onerror
和 window.addEventListener('error')
是基本一样的,但是 onerror
无法捕获资源加载失败,关于onerror浏览器兼容性可以看这篇文章
// useCapture 需要设置 true
// 事件冒泡
window.addEventListener('error', (e) => {
console.log(e)
console.log(e.message)
console.log(e.source)
console.log(e.lineno)
console.log(e.colno)
console.log(e.error)
// 禁止默认错误提示
e.preventDefault();
}, true);
- message:错误信息(字符串)。可用于HTML onerror=””处理程序中的event。
- source:发生错误的脚本URL(字符串)
- lineno:发生错误的行号(数字)
- colno:发生错误的列号(数字)
- error:Error对象(对象)
unhandledrejection
The
unhandledrejection
event is sent to the global scope of a script when a JavaScriptPromise
that has no rejection handler is rejected; typically, this is thewindow
, but may also be aWorker
. This is useful for debugging and for providing fallback error handling for unexpected situations.
用来捕获 Promise
未处理 reject
,但是返回的信息只有 promise
和 reason
,没有其他具体信息
window.addEventListener("unhandledrejection", event => {
console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
}, true);
今天的文章JS错误捕获分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18463.html