try-catch仅捕获同步异常,无法处理异步错误、Promise拒绝、全局错误、资源加载失败及Web Worker错误;需配合window.onerror、unhandledrejection等全局监听机制分层兜底。

仅靠 try-catch 不足以覆盖 JavaScript 中的全部错误场景。它只能捕获同步代码中抛出的异常,对异步错误、全局错误、资源加载失败、Promise 拒绝等完全无能为力。
哪些错误 try-catch 根本抓不到
这是最容易被忽略的前提:你以为包住就安全了,其实很多崩溃根本进不了 catch 块。
- 异步回调里的
throw(如setTimeout(() => { throw new Error('boom') }, 100))——不会触发外层try-catch - 未处理的 Promise 拒绝(
Promise.reject(new Error('no catch'))且没接.catch()或await) - 全局错误(如顶层语法错误、
ReferenceError在模块作用域直接执行时) - 资源加载失败(
、fetch()网络超时但没加catch) - Web Worker 内部错误(完全隔离的执行上下文)
必须搭配的全局错误监听机制
要真正“兜底”,得在运行时环境层面补上缺失的监听点。不同错误类型对应不同 API:
- 同步/异步抛出的未捕获错误 → 监听
window.onerror(浏览器)或process.on('uncaughtException')(Node.js) - 未处理的 Promise 拒绝 → 必须监听
window.addEventListener('unhandledrejection')(浏览器)或process.on('unhandledRejection')(Node.js) - 资源加载失败 → 单独为
、等元素绑定onerror事件,或用document.addEventListener('error', ...)(注意会冒泡,需过滤)
window.addEventListener('unhandledrejection', event => {
console.error('Unhandled promise rejection:', event.reason);
// 上报错误、记录日志、展示友好提示
event.preventDefault(); // 阻止默认控制台警告(可选)
});
try-catch 的正确使用姿势
它不是摆设,但要用在刀刃上:只包裹明确可能抛错的同步逻辑,避免滥用和掩盖问题。
立即学习“Java免费学习笔记(深入)”;
- 不要包裹整个函数体,尤其不要包裹含异步操作的函数(
async函数内仍需单独try-catchawait 表达式) - 避免空
catch块:catch (e) { }是最危险的习惯,至少要console.error(e)或上报 - 区分错误类型再处理:
if (e instanceof TypeError)比笼统catch更可控 - Promise 链中,
.catch()和try-catch+await效果等价,但后者更符合直觉;注意Promise.all()会因任一拒绝而中断,需用Promise.allSettled()替代
async function fetchUser() {
try {
const res = await fetch('/api/user');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (e) {
// 这里能捕获 fetch 失败、JSON 解析错误、手动 throw
console.error('Fetch failed:', e);
throw e; // 不要静默吞掉,让调用方决定如何处理
}
}
真正健壮的错误处理,是分层的:局部 try-catch 应对已知可恢复错误,全局监听器负责兜底和可观测性。漏掉任意一层,都可能让错误悄无声息地变成用户眼中的白屏或卡死。











