【JavaScript】JS中的异常处理
2023/02/07 16:59:09
优雅的异常处理方式就像冒泡事件,任何元素可以自由拦截,也可以放任不管交给顶层处理。
try-catch 能捕获到哪些异常
try-catch 语句只能捕获在 try-catch 语句执行期间抛出的异常。
下面这个例子中,由于异常是在定时器中抛出的,抛出异常时 try-catch 语句已经执行完毕(任务队列),所以这个异常未被捕获:
try {
setTimeout(() => {
throw Error("请求失败");
});
} catch (error) {
console.log("触发异常", error); // 永远不会执行
}
// 程序崩溃
// Uncaught Error: 请求失败
Promise 中的异常
在文章:promise 实现原理解析中已经解析过, Promise 会将接收到的函数整体包裹一层 try-catch
语句后执行,并将错误对象作为 拒绝原因
传递给 reject()
方法,因此只需要用 .catch()
语句就可以获取到错误对象。
Promise.resolve()
.then(() => {
throw new Error("请求失败");
})
.catch(console.log);
因为在 Promise 内部也是用 try-catch 语句捕获异常,如果是在定时器中抛出的异常同样无法捕获:
Promise.resolve()
.then(() => {
setTimeout(() => {
throw new Error("请求失败");
});
})
.catch(console.log);
Promise 中没有 catch 的异常
如果一个 Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection
事件:
window.addEventListener("unhandledrejection", (event) => {
console.log("unhandledrejection", event);
});
Promise.reject(1);
全局的事件处理
浏览器环境
浏览器环境中可以通过绑定 onerror
事件来监听抛到全局的异常,但是只能监听到抛出异常事件,不能阻止异常阻断进程。
onerror
事件只能接收到错误对象的 message 信息:
throw new Error(1);
window.onerror = (err) => {
console.log(err); // Uncaught Error: 1
console.log(typeof err); // string
};
用 addEventListener
绑定时可以获取事件对象,事件对象中包含异常的错误对象:
throw new Error(1);
window.addEventListener("error", (event) => {
console.log(event.error);
console.log(Object.prototype.toString.call(event.error)); // [object Error]
});
NodeJS 环境
NodeJS 中如果有未捕获的异常会导致系统崩溃,可以通过监听 uncaughtException
事件来监听未捕获的异常,保证应用不会崩溃:
process.on("uncaughtException", (e) => {
console.error("process error is:", e.message);
});
其他处理可见这篇文章:Node 中如何守护进程
参考
Callback Promise Generator Async-Await 和异常处理的演进