error.cause 是 ES13 引入的标准属性,用于手动关联原始错误以保留异步链中丢失的堆栈、name、code 等上下文,需在 new Error(msg, { cause }) 中显式传入,不自动继承。

error.cause 是 ECMAScript 2022(ES13)引入的标准属性,用于在抛出新错误时显式关联原始错误,从而保留异步链中被“吞掉”或“包装”的异常上下文。它不是自动继承的,必须手动设置,尤其在 try/catch + throw new Error() 或 Promise 链中容易丢失原始堆栈和信息。
为什么异步错误中原始上下文容易丢失?
常见场景如:
- Promise 中
catch后重新 throw 新错误(未传 cause)→ 原始堆栈、name、code 等全部丢失 - async 函数内 try/catch 捕获错误后,用
throw new Error('业务失败')→ 只剩新消息,原始错误被丢弃 - 第三方库封装错误但没透传 cause → 调试时无法追溯源头
正确使用 error.cause 保留原始异常
核心原则:捕获原始错误后,在新建错误实例时,将其作为 cause 选项传入构造函数(支持 Error 及其子类):
async function fetchUser(id) {
try {
const res = await fetch(`/api/user/${id}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
} catch (originalError) {
// ✅ 正确:显式关联原始错误
throw new Error('获取用户失败', { cause: originalError });
}
}
这样抛出的错误具备:
立即学习“Java免费学习笔记(深入)”;
-
error.cause === originalError(严格相等) -
error.cause.stack完整保留原始堆栈 -
error.cause.name、error.cause.message等属性可用
在 Promise 链中安全透传 cause
避免在 .catch() 中直接 throw 'string' 或 throw new Error()。应检查是否已有 cause,并延续它:
fetch('/api/data')
.then(res => res.json())
.catch(err => {
// ✅ 保留原始 err,再包装一层语义化错误
throw new Error('解析响应数据失败', { cause: err });
})
.catch(err => {
console.error('顶层错误:', err.message);
console.error('原始错误:', err.cause?.message);
console.error('原始堆栈:', err.cause?.stack);
});
兼容性与降级建议
目前主流浏览器和 Node.js ≥16.9 已支持 cause 选项。若需兼容旧环境:
- 可手动在错误实例上挂载
cause属性(非标准,但能被多数调试工具识别):err.cause = originalError - 使用 error-cause polyfill(仅适用于支持
ErrorOptions的运行时) - 日志中显式打印
originalError.stack作为补充
注意:V8 和 Chrome DevTools 已原生支持展开 error.cause,在控制台点击错误即可逐层查看。


















