RangeError — Stack Overflow & Invalid Values
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5), ESLint can detect some recursive patterns and missing base cases via linting rules, but stack overflow from RangeError itself often manifests only at runtime with specific input depths; catching the actual crash requires runtime testing or profiling, not static analysis.
Closest to 'simple parameterised fix' (e3), the quick_fix of adding depth counters is a localised change within a function or small refactor to replace recursion with iteration in one component; no cross-file coordination needed.
Closest to 'localised tax' (b3), the choice to use or avoid deep recursion affects individual functions and their callers, but doesn't reshape the broader architecture; however, if recursion is endemic to a codebase, retrofitting depth limits becomes a persistent tax.
Closest to 'serious trap' (t7), the misconception that try/catch always catches stack overflow RangeError contradicts normal exception-handling expectations; developers expect catch blocks to work, but engine crashes before the catch can run, violating the principle of exception safety that applies to other error types in the same language.
TL;DR
Explanation
RangeError: Maximum call stack size exceeded is the most common form — infinite or too-deep recursion. Other causes: new Array(-1) (negative size), toFixed(200) (precision out of range), String.fromCodePoint(Infinity). Unlike ReferenceError (undeclared variable) or TypeError (wrong type), RangeError is about a value being outside its valid numeric or structural range. Catching: try/catch catches RangeError from bad API calls but NOT stack overflow from recursion in most engines — stack overflow crashes the current execution context. Detection: check for recursion with a depth counter, use iterative algorithms for large inputs.
Common Misconception
Why It Matters
Common Mistakes
- Recursive functions without a base case or depth limit.
- Calling toFixed() with user-supplied precision — can be > 100 (throws RangeError).
- Not knowing new Array(n) throws for negative n.
Code Examples
function flatten(arr) {
return arr.reduce((acc, val) =>
Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), []
);
}
flatten(deeplyNestedArray); // RangeError: Maximum call stack size exceeded
// Iterative with explicit stack:
function flatten(arr) {
const stack = [...arr];
const result = [];
while (stack.length) {
const item = stack.pop();
if (Array.isArray(item)) stack.push(...item);
else result.push(item);
}
return result.reverse();
}
// Or with depth limit:
function flatten(arr, depth = 10) {
if (depth === 0) return arr;
return arr.flat(depth);
}