JavaScript前端常见异常及如何捕获详解
本文详解JavaScript前端常见异常的捕获机制,涵盖全局捕获(window.onerror、unhandledrejection)、框架级处理(React ErrorBoundary、Vue errorHandler)及业务侧局部捕获。重点解析try-catch的适用范围、Promise异步异常处理差异及接口请求拦截策略,帮助开发者构建健壮的错误处理体系。
从架构层面探讨全局异常捕获策略。
在原生JavaScript中,可通过window.onerror或window.addEventListener('error')实现全局异常捕获。
针对Promise未处理的拒绝状态,可通过监听unhandledrejection事件进行全局捕获。
现代前端框架通常提供框架级的全局异常捕获机制。
在React中,利用ErrorBoundary组件来捕获子组件树中的渲染错误。
// ErrorBoundary的示例
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
// 在这里可以做异常的上报
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
在Vue中,通过配置Vue.config.errorHandler来统一处理应用中的错误。
对于axios请求,可通过配置interceptors统一处理底层请求异常。
从框架层面探讨全局异常捕获策略。
Vue通过errorHandler配置,React通过componentDidCatch生命周期方法实现框架级错误捕获。
从业务代码层面探讨局部异常捕获策略。
对可能存在风险的代码块使用try-catch进行包裹。
try-catch仅能捕获运行时非异步错误,无法捕获语法错误和异步错误,这一点需要特别注意。
应合理使用try-catch,避免过度使用。部分异常需要抛出给外部统一处理。
以下是一些常见需要特别注意并使用try-catch包裹的情况。
JSON解析必须使用try-catch捕获异常,以防格式错误导致程序崩溃。
try {
const res=fetch(*)
JSON.parse(res); // res 为服务端返回的数据
} catch(e) {
// 捕获到详细的错误,在这里处理日志上报或其他异常处理等逻辑,如是否提示用户,是否有异常下的兜底数据,比如使用缓存数据等
console.error("服务端数据格式返回异常,无法解析", res);
}
// 注意:下面的异常try catch无法捕获
try {
setTimeout(() => {
undefined.map(v => v);
}, 1000)
} catch(e) {
console.log("捕获到异常:", e);
}
async/await异步请求场景下的异常处理。
正则表达式处理过程中的异常捕获。
Buffer处理过程中的异常捕获。
Promise异常处理机制。
需注意,未被捕获的Promise异常会作为全局异常抛出。
局部Promise捕获主要有两种方式。
// 1. Promise().catch()
let promise = new Promise((resolve,reject)=>{}).catch(e=>{
// handle error
})
// 2. async/await + try/catch
let promise = new Promise();
async function test() {
try {
await promise;
} catch (e) {
// handle error
}
}
使用Promise().catch()方法进行捕获。
全局Promise异常可通过window.addEventListener("unhandledrejection")进行监听。
需要特别注意以下几点。
Promise自身的异常只能被自己的catch捕获,或在try/catch中以await方式调用才能捕获。否则将作为ERR_UNHANDLED_REJECTION异常抛出到全局。
外层Promise无法捕获内层Promise抛出的异常。
let p1 = new Promise(async (resolve, reject) => {
return reject(100); // 被捕获
});
async function fn() {
try {
let result = await p1;
console.log(2, result); //这里不会执行
} catch (e) {
console.log("e:", e); //这里不会执行
}
}
fn();
let p1 = new Promise(async (resolve, reject) => {
return reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
});
function fn() {
try {
let result = p1;
console.log(2, result); //这里不会执行
} catch (e) {
console.log("e:", e); //这里不会执行
}
}
fn();
let p1 = new Promise(async (resolve, reject) => {
console.log("after reject");
return Promise.reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
});
async function fn() {
try {
let result = await p1;
console.log(2, result); //这里不会执行
} catch (e) {
console.log("e:", e); //这里不会执行
}
}
fn();
let p1 = new Promise(async (resolve, reject) => {
return Promise.reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
}).catch((e) => {
console.log("promise out e", e); // 这里不会执行
});
async function fn() {
try {
let result = await p1;
console.log(2, result); //这里不会执行
} catch (e) {
console.log("e:", e); //这里不会执行
}
}
fn();
Promise中同步抛出的异常会触发Promise.reject并被捕获;但异步抛出的异常不会触发Promise.reject,因此不会被捕获。
new Promise((resolve, reject) => {
throw new Error("Error1"); // 等效于reject
}).catch((e) => {
console.log("异常被捕获到了1");
});
new Promise(async (resolve, reject) => {
reject(new Error("Error2"));
}).catch((e) => {
console.log("异常被捕获到了2");
});
new Promise(async () => {
throw new Error("Error3");
}).catch((e) => {
console.log("异常被捕获到了3");
});
接口请求异常的捕获与处理。
Fetch请求结合async/await与try-catch进行异常处理。
Axios请求中,需自行处理自定义的异常上报逻辑。
全局静态资源异常的监控策略。
可通过window.addEventListener("error")或资源标签的onError属性进行监控。
到此这篇关于JavaScript前端常见异常及如何捕获详解的文章就介绍到这了,更多相关JavaScript异常捕获内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
JS动态构建复杂嵌套JSON对象的方法
2026-11-05 15:41:52
JS负数取余为什么是负数?详解余数与模运算区别
2026-11-05 13:34:41
JS 解压出现乱码或报错怎么解决?
2026-11-05 12:32:38
JS 中 startsWith、indexOf 与正则判断字符串前缀的对比
2026-11-04 22:19:43
JS解析Excel后怎么将数据转换为JSON格式
2026-11-04 20:58:28
