应使用 throw new Error("消息") 以完整保留堆栈;抛出字符串或普通对象会导致 stack 丢失;重抛时推荐 new Error(msg, { cause }) 或 Object.assign 继承 stack;自定义错误须继承 Error 并调用 super()。

直接用 throw new Error("消息") 即可完整保留原始错误堆栈,无需额外操作 —— 关键在于**不要抛出字符串或普通对象**。
必须用 Error 构造函数实例
JavaScript 引擎只为 Error 及其子类(如 SyntaxError、TypeError)自动捕获并填充 stack 属性。抛出其他值(如字符串、字面量对象)会导致堆栈丢失或为空。
- ✅ 正确:
throw new Error("用户未登录")→ 堆栈包含调用位置 + 错误创建位置 - ❌ 错误:
throw "用户未登录"→stack为undefined或空字符串 - ❌ 错误:
throw { message: "用户未登录" }→ 无stack,也不是Error实例
重抛错误时别覆盖原始堆栈
在 catch 中想补充信息再抛出,应基于原错误构造新 Error,并手动继承 stack(现代环境支持 cause 属性):
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 兼容写法:
throw Object.assign(new Error("网络请求失败:" + err.message), { stack: err.stack }) - 现代写法(Chrome 93+/Node.js 16.9+):
throw new Error("网络请求失败", { cause: err }),err.stack自动保留在error.cause.stack
自定义错误类要继承 Error
若需语义化错误类型(如 ValidationError),必须用 class ValidationError extends Error,并在构造函数中调用 super(message):
- ✅ 正确:继承 + super 调用 → 堆栈正常
- ❌ 错误:仅设
this.name = "ValidationError"但不继承Error→ 无有效堆栈
避免在异步回调中意外丢失堆栈
Promise 链中若用 throw 抛出非 Error,虽能被 catch 捕获,但堆栈指向 Promise 内部而非实际出错行:
- ✅ 推荐:
Promise.reject(new Error("验证失败")) - ⚠️ 注意:
setTimeout(() => { throw "timeout" })的堆栈无法追溯到调用方,应改用setTimeout(() => { throw new Error("timeout") })
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










