No Catch-Parameter Reassignment
ID |
javascript.catch_variable_reassigned |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
JavaScript |
Tags |
code-smell, suspicious-assignment |
Description
Reports assignments to the parameter of a catch clause. After try {…} catch (err) {…}, writing err = something; inside the handler discards the original error reference, breaking diagnostics that relied on it (logging, rethrows, root-cause chains).
Property assignments such as err.detail = … are not reported — those mutate the caught object, which is sometimes intentional. Only the binding itself is protected.
Rationale
-
Loggers, stack-trace serializers, and error-reporting tools all expect
errto point at the originally-thrown object. After reassignment, the cause is lost forever and the new value (often a string or a wrapper) replaces the chain. -
If a wrapping pattern is desired, declare a separate binding (
const wrapped = new Error(…)) and rethrow that — this preserves the original viawrapped.cause. -
Catch parameters are scoped to the handler. Reassigning them inside has no effect on outer code, so it cannot even be a side-channel — it is purely local damage.
// Bad
try {
doWork();
} catch (err) {
err = new Error("wrapped"); // root cause is gone forever
log(err);
}
Remediation
Use a fresh binding (and cause to keep the original error intact) instead of overwriting err.
// Good
try {
doWork();
} catch (err) {
const wrapped = new Error("wrapped", { cause: err });
throw wrapped;
}