preserve-caught-error
重新抛出自定义错误时,禁止丢失最初捕获的错误
在 配置文件 中使用来自 @eslint/js 的 recommended 配置可以启用此规则
此规则报告的一些问题可通过编辑器 建议 手动修复
JavaScript 开发者经常在 catch 块中重新抛出错误以添加上下文,但忘记保留原始错误,导致调试信息丢失。
🌐 JavaScript developers often re-throw errors in catch blocks to add context but forget to preserve the original error, resulting in lost debugging information.
在抛出新错误时使用 cause 选项有助于保留原始错误并保持完整的错误链,从而提高可调试性和可追踪性。
🌐 Using the cause option when throwing new errors helps retain the original error and maintain complete error chains, which improves debuggability and traceability.
try {
await fetch("https://xyz.com/resource");
} catch(error) {
// Throw a more specific error without losing original context
throw new Error("Failed to fetch resource", {
cause: error
});
}
规则详情
🌐 Rule Details
此规则强制在 catch 块中抛出新错误时使用 cause 属性。
🌐 This rule enforces the use of the cause property when throwing a new error inside a catch block.
检查所有支持传递 cause 的内置 error types。
🌐 Checks for all built-in error types that support passing a cause.
此规则的错误代码示例:
🌐 Examples of incorrect code for this rule:
/* eslint preserve-caught-error: "error" */
// Not using the `cause` option
try {
// ...
} catch (error) {
throw new Error("Something went wrong: " + error.message);
}
// Throwing a new Error with unrelated cause
try {
doSomething();
} catch (err) {
const unrelated = new Error("other");
throw new Error("Something failed", { cause: unrelated });
}
// Caught error is being lost partially due to destructuring
try {
doSomething();
} catch ({ message, ...rest }) {
throw new Error(message);
}
// Cause error is being shadowed by a closer scoped redeclaration.
try {
doSomething();
} catch (error) {
if (whatever) {
const error = anotherError; // This declaration is the problem.
throw new Error("Something went wrong", { cause: error });
}
}
符合此规则的正确代码示例:
🌐 Examples of correct code for this rule:
/* eslint preserve-caught-error: "error" */
try {
// ...
} catch (error) {
throw new Error("Something went wrong", { cause: error });
}
// When the thrown error is not directly related to the caught error.
try {
} catch (error) {
foo = {
bar() {
// This throw is not directly related to the caught error.
throw new Error("Something went wrong");
}
};
}
// No throw inside catch
try {
doSomething();
} catch (e) {
console.error(e);
}
// Ignoring the caught error at the parameter level
// This is valid by default, but this behavior can be changed
// by using the `requireCatchParameter` option discussed below.
try {
doSomething();
} catch {
throw new TypeError("Something went wrong");
}
选项
🌐 Options
此规则只有一个选项 - 一个具有以下可选属性的对象:
🌐 This rule takes a single option — an object with the following optional property:
requireCatchParameter:当设置为true时,要求 catch 块始终包含被捕获的错误参数。默认情况下为false。
requireCatchParameter
启用此选项要求所有的 catch 块都必须有一个捕获的错误参数。这确保了捕获的错误不会在参数级别被丢弃。
🌐 Enabling this option mandates for all the catch blocks to have a caught error parameter. This makes sure that the caught error is not discarded at the parameter level.
"preserve-caught-error": ["error", {
"requireCatchParameter": true
}]
针对 { "requireCatchParameter": true } 选项的错误代码示例:
🌐 Example of incorrect code for the { "requireCatchParameter": true } option:
/* eslint preserve-caught-error: ["error", { "requireCatchParameter": true }] */
try {
doSomething();
} catch { // Can't discard the error ❌
throw new Error("Something went wrong");
}
{ "requireCatchParameter": true } 选项的正确代码示例:
🌐 Example of correct code for the { "requireCatchParameter": true } option:
/* eslint preserve-caught-error: ["error", { "requireCatchParameter": true }] */
try {
doSomething();
} catch(error) { // Error is being referenced ✅
// Handling and re-throw logic
}
何时不使用
🌐 When Not To Use It
如果你符合以下情况,则可能不想启用此规则:
🌐 You might not want to enable this rule if:
- 你遵循自定义错误处理方法,其中故意从重新抛出的错误中省略原始错误(例如,为了避免暴露内部详细信息或单独记录原始错误)。
- 你使用第三方或内部的错误处理库,这些库通过非标准属性(例如 verror)保留错误上下文,而不是使用 cause 选项。
- (在罕见情况下)你正在针对不支持
Error构造函数中 cause 选项的旧环境。
版本
此规则是在 ESLint v9.35.0 中引入。