Error.prototype.cause 是 ES2022 引入的标准属性,用于显式声明错误的根本原因,解决传统错误重抛时原始错误丢失的问题,支持多层嵌套、自动链式展示及手动遍历,现代环境已广泛支持。

Error.prototype.cause 是 ECMAScript 2022(ES13)引入的标准化属性,用于显式声明一个错误的“根本原因”,从而在抛出新错误时保留原始错误链条。它让嵌套错误具备可追溯的因果关系,大幅改善多层调用、异步封装或错误重抛场景下的调试体验。
为什么需要 cause 属性?
传统 JavaScript 中,当在 catch 块中抛出新错误(比如包装错误信息、添加上下文),原始错误对象通常丢失:
try {
JSON.parse('{"invalid": }'); // SyntaxError
} catch (err) {
throw new Error('Failed to parse config'); // 原始 SyntaxError 被丢弃
}
这导致堆栈中断、无法访问原始 error.name、error.message 或自定义字段。而 cause 提供了标准、语义明确的方式把原始错误“挂载”到新错误上。
如何正确使用 cause 选项构造错误
目前仅 Error 构造函数支持传入 options 对象并设置 cause(Chrome 93+、Firefox 94+、Safari 16.4+、Node.js 16.9+):
- 直接传递原始错误对象作为
cause值 - cause 可以是任意值(不限于 Error 实例),但推荐传 Error 以保持链路可用
- 多个嵌套层级可逐级设置 cause,形成深度链
try {
await fetch('/api/data');
} catch (err) {
// 包装网络错误,保留原始 err
throw new Error('API request failed', { cause: err });
}
如何读取和遍历错误链
浏览器和 Node.js 运行时会自动在错误格式化(如 console.error、Node.js 的 stack trace)中展示 cause 链。你也可以手动访问:
-
error.cause直接获取被设置的 cause 值 - 递归检查
error.cause?.cause可展开多层原因 - 现代 DevTools(Chrome、VS Code Debug Console)点击堆栈中的 Caused by 可跳转查看原始错误详情
function logErrorChain(err, depth = 0) {
const indent = ' '.repeat(depth);
console.error(`${indent}→ ${err.message} (${err.name})`);
if (err.cause) {
console.error(`${indent} Caused by:`);
logErrorChain(err.cause, depth + 1);
}
}
兼容性与降级建议
在不支持 cause 的环境中(如旧版 Node.js 或 IE),该属性会被静默忽略。为保障可调试性:
- 始终保留原始错误的
stack或关键字段(如err.message)拼接到新错误 message 中 - 给错误实例手动添加
cause属性(仅作数据标记,不触发运行时链式渲染) - 使用工具库如 airbnb/javascript 错误处理规范 或
wrap-error等做 polyfill 式封装
// 兼容写法示例
function wrapError(message, originalErr) {
const err = new Error(message);
err.cause = originalErr;
err.originalStack = originalErr?.stack;
return err;
}

















