Linter · Rules
preserve-caught-error
Require the caught error as the cause of a new error thrown in catch
When a catch block throws a new error, the one it caught is gone, along with its message and stack trace. The log says "Could not load the config" but not why. Pass the caught error as cause to keep both.
The rule checks throw new Error() in a catch block, and the other built-in classes such as TypeError and AggregateError. A throw in a function inside the block isn't checked.
The report comes with a suggestion that adds { cause: error }.
This rule is on by default.
Configure
On by default as a warning. To turn it off:
[lint.rules]
"preserve-caught-error" = "off" # or "error"
Every option, set to its default:
[lint.rules]
"preserve-caught-error" = ["warn", {
requireCatchParameter = false,
errorClassNames = [], # list of strings or objects
}]
Examples
Reported:
try {
loadConfig();
} catch (error) {
throw new Error("Could not load the config");
}
The cause must be the caught error itself, not a part of it:
try {
loadConfig();
} catch (error) {
throw new Error("Could not load the config", { cause: error.message });
}
Destructuring the parameter loses the rest of the error:
try {
loadConfig();
} catch ({ message }) {
throw new Error(`Could not load the config: ${message}`);
}
Not reported:
try {
loadConfig();
} catch (error) {
throw new Error("Could not load the config", { cause: error });
}
try {
saveConfig();
} catch (error) {
report(error);
throw error;
}
Options
| Option | Default | What it does |
|---|---|---|
requireCatchParameter | false | Also report a new error thrown in a catch that has no parameter. |
errorClassNames | [] | Your own error classes to check as well. |
try {
loadConfig();
} catch {
throw new Error("Could not load the config");
}
Each errorClassNames entry is the name of a class that takes { cause } as its second argument, like Error:
try {
loadConfig();
} catch (error) {
throw new ConfigError("Could not load the config");
}
If { cause } is a different argument, make the entry an object that says which one, counting from 1:
try {
await fetchUser(id);
} catch (error) {
throw new HttpError(502, "Could not fetch the user");
}
try {
await fetchUser(id);
} catch (error) {
throw new HttpError(502, "Could not fetch the user", { cause: error });
}