# 异常捕获
# 1、错误类型
# 1、常规运行时错误
let a;
console.log(a.length); // TypeError: Cannot read properties of undefined (reading 'length')
1
2
2
# 2、语法错误
const a; // The constant "b" must be initialized
1
这种错误在代码编译阶段就会出问题。
# 3、异步中的错误
setTimeout(() => {
let a;
console.log(a.length)
}, 1000);
1
2
3
4
2
3
4
# 4、资源加载错误
<script src='https://www.testing.com/react'></script>
<img src="https://www.testing.com/picker.png" />
1
2
2
资源加载不到时的报错。
# 5、promise 的报错
new Promise((resolve, reject) => {
setTimeout(() => {
reject(99);
}, 1000);
}).then((val) => {
console.log('val: ', val);
});
1
2
3
4
5
6
7
2
3
4
5
6
7
# 6、async/await中的错误
const val = await (async () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(99);
}, 1000);
});
})();
1
2
3
4
5
6
7
2
3
4
5
6
7
特别注意
- 1、Promise 的 reject 错误在没有被 reject 回调或者 catch 捕获到的时候才能被
unhandledrejection
事件捕获; - 2、Promise 中错误不能通过
try...catch
的方式捕获; - 3、async/await 中的错误 通过
try...catch
的方式捕获, 也可以通过unhandledrejection
事件捕获。
# 2、捕获异常的方式 - try/catch
- 1、常规运行时的错误;
- 2、async/await 中的异常(未被处理过);
- 3、async/await 中的 reject(未被处理过)。
# 3、捕获异常的方式 - window.onerror
window.onerror = (message, source, lineno, colno, error) => {
console.log('message, source, lineno, colno, error: ', message, source, lineno, colno, error);
};
1
2
3
2
3
- 1、常规运行时的错误;
- 2、异步错误(宏任务 - setTimeout、setInterval);
# 4、捕获异常的方式 - error 事件
const handleError = (error) => {
console.log('=======error: ', error);
};
window.addEventListener('error', handleError, true);
1
2
3
4
2
3
4
- 1、常规运行时的错误;
- 2、资源错误;
- 3、异步错误(宏任务 - setTimeout、setInterval);
# 5、捕获异常的方式 - unhandledrejection 事件
const handleUnhandledrejection = (event) => {
console.log('error=======: ', event);
// event.preventDefault();
};
window.addEventListener('unhandledrejection', handleUnhandledrejection);
1
2
3
4
5
2
3
4
5
前提是:未被reject回调或者catch接收;
- 1、Promise 中的异常;
- 2、Promise 中的 reject;
- 3、async/await 中的异常;
- 4、async/await 中的 reject。
# 6、总结
常规运行时错误 | 异步错误 | 资源加载错误 | Promise中的异常/reject | async/await中的异常/reject | |
---|---|---|---|---|---|
try/catch | √ | - | - | - | √ |
window.onerror | √ | √ | - | - | - |
error事件 | √ | √ | √ | - | - |
unhandledrejection 事件 | - | - | - | √ | √ |
# 7、vue - errorCaptured 生命周期期
该生命周期会监听所有下级组件的错误,可以返回false阻止向上传播,可能会有多个上级节点都在监听错误。
errorCaptured(error, instance, info) {
console.log('error, instance, info: ', error, instance, info);
}
1
2
3
2
3
# 8、vue - errorHandler
全局的错误监听,所有的组件的报错都会汇总到这里。 errorCaptured 返回false 则不会。
const app = createApp(App);
app.config.errorHandler = (error, instance, info) {
console.log('error, instance, info: ', error, instance, info);
};
1
2
3
4
2
3
4
WARNING
errorhandler 会阻止错误走向 window.onerror。
# 9、react - ErrorBoundary
React 16+ 引入,可以监听所有下级组件的报错,同时降级展示UI。
ReactDom.render(
<React.StrictMode>
<ErrorBoundary>
<App />
</ErrorBoundary>
</React.StrictMode>
)
1
2
3
4
5
6
7
2
3
4
5
6
7