try-catch仅捕获同步异常,对异步错误、语法错误、未await的Promise、事件处理器内错误无效;需await才能捕获async/await中的Promise错误;catch参数可解构但须注意兼容性;finally适合清理但不应抛错或引入新异常。

try-catch 会捕获哪些错误
try-catch 只捕获**同步执行中抛出的异常**,比如 throw new Error()、类型错误(TypeError)、引用错误(ReferenceError)等。它对以下情况完全无效:
- 异步代码中的错误(如
setTimeout、fetch回调、Promise拒绝) - 语法错误(
SyntaxError)——脚本根本不会执行到try块 - 未捕获的 Promise rejection(即使在
try内创建了 Promise,不await或不加.catch()就会漏掉) - 事件处理器内的错误(如
onclick中抛错,除非你在 handler 内部手动包try-catch)
async/await 中 try-catch 必须 await
写 async 函数时,try-catch 只对 await 的 Promise 生效;漏掉 await 就等于把 Promise 当普通对象返回,错误不会进入 catch。
async function bad() {
try {
fetch('/api'); // ❌ 没 await,fetch 返回 Promise 但不等待,错误被忽略
} catch (e) {
console.error(e); // 这里永远不会执行
}
}
async function good() {
try {
const res = await fetch('/api'); // ✅ await 后,网络错误、4xx/5xx 都进 catch
if (!res.ok) throw new Error(`HTTP ${res.status}`);
} catch (e) {
console.error('请求失败:', e.message);
}
}
catch 参数不是必须叫 err
catch 后的参数只是形参,名字任意,但必须存在。常见写法是 catch (error) 或 catch (e),但要注意:
- 不要写成
catch (err.message)—— 这是语法错误,JS 不支持解构式捕获 - 可以写
catch ({ message, name })来直接解构错误对象属性(ES2015+ 支持) - 若需兼容旧环境或确保安全,先检查
error instanceof Error,再访问message,因为某些错误(如字符串throw 'oops')没有message属性
finally 适合放清理逻辑,但别 throw
finally 总会执行,适合关流、重置状态、隐藏 loading 等。但要注意:
立即学习“Java免费学习笔记(深入)”;
- 如果
finally中throw或返回 rejected Promise,它会覆盖try或catch中的返回值或错误 - 不要在
finally里做可能失败的操作(比如又发一个可能出错的fetch),否则会掩盖原始错误 - 想确保某段代码“一定执行且不影响原有流程”,就只做同步、无副作用的操作,例如:
loading.value = false
catch 打印 e.message,大概率查不到问题源头。需要主动保留 e.stack,并在日志中透出完整信息。










