JavaScript stack overflow error
From time to time, I’ve blogged about JavaScript browser limits and how they present themselves. I started out by discussing the long-running script dialog and then moved on to other performance issues. I thought I had covered most of the annoying and ill-explained JavaScript limits, but this past week I ran across another that is worth discussing: stack overflow errors.
I’ve written about how too much recursion can lead to performance issues. Most browsers have limits on how much recursion is allowed before the script is automatically canceled. This is a limit that is separate from the one determining if the script is long-running. And the limit is really less about recursive calls so much as it is about the size of the JavaScript call stack.
Not surprisingly, different browsers have different call stack sizes. Also not surprisingly, the method that they use to determine the call stack varies as well. The various call stack sizes I could measure are (give or take, might be off by 1 or 2):
- Internet Explorer 7: 1,789
- Firefox 3: 3,000
- Chrome 1: 21,837
- Opera 9.62: 10,000
- Safari 3.2: 500
Some have said, but I cannot confirm, that IE and Opera’s call stack size are somewhat tied to the amount of RAM on the system. All other browsers have this set by a default. It’s also worth noting that WebKit seems to have a much higher limit and that Safari imposes a stricter limit on the JavaScript engine.
There are two common scenarios in which this limit could be reached. The first is simple recursion, such as:
function recurse(){
recurse();
}
recurse();
The second is a more devious and harder-to-identify issue, especially in large code bases, where two functions each call the other, such as:
function doSomething(){
doSomethingElse();
}
function doSomethingElse(){
doSomething();
}
doSomething();
In each case, the browser will end up stopping your code and (hopefully) display a message about the issue:
- Internet Explorer 7: “Stack overflow at line x”
- Firefox 3:”Too much recursion”
- Chrome 1: n/a
- Opera 9.62: “Abort (control stack overflow)”
- Safari 3.2:”RangeError: Maximum call stack size exceeded.”
Chrome is the only browser that doesn’t display a message indicating the problem. If you see any of these error messages pop up, it means one of the two patterns are involved and need to be changed. There’s usually a line number and file name associated with this error, so it’s fairly straightforward to debug.
Perhaps the most interesting part of stack overflow errors is that they are actual JavaScript errors in some browsers, and can therefore be trapped using a try-catch statement. The exception type varies based on the browser being used. In Firefox, it’s an InternalError, in Safari and Chrome, it’s a RangeError, and Internet Explorer throws a generic Error type (Opera doesn’t throw an error, it just stops the JavaScript engine) . So, it’s possible to do something like this:
try {
recurse();
} catch (ex){
alert("Too much recursion!");
}
If left untrapped, these errors bubble up as any other error would (in Firefox, it ends up in the Firebug console, Safari/Chrome it shows up in the console) except in Internet Explorer. IE will not only display a JavaScript error but will also display an ugly dialog box that looks just like an alert with the stack overflow message.
Now, just because it’s possible to trap this error in almost all browsers doesn’t mean that you should. No code should end up in production with even the possibility of a stack overflow error present. Such instances indicate poor code design and should be re-evaluated and/or re-designed to avoid this error. Consider this post as an aid in debugging this issue, not as a license to trap and disguise it.
Disclaimer: Any viewpoints and opinions expressed in this article are those of Nicholas C. Zakas and do not, in any way, reflect those of my employer, my colleagues, Wrox Publishing, O'Reilly Publishing, or anyone else. I speak only for myself, not for them.
Both comments and pings are currently closed.




7 Comments
Maybe interesting to know: An other stack overflow(?) that crashes IE8. In only two or three lines of javascript.
http://www.domnodes.org/wp/?p=11
J.S. on May 19th, 2009 at 9:43 am
Hi Zakas,
Just running the same test on my machines/oss/browsers I got some interesting numbers/errors:
on Ubuntu 8.04:
- Firefox 3.0.10: 3000 (InternalError: too much recursion)
- Chromium 2.0.174.0~svn20090412r13572: 21828 (RangeError: Maximum call stack size exceeded)
- Rhino 1.4r2: 338 (js: exception from uncaught JavaScript throw: java.lang.StackOverflowError)
- SpiderMonkey 1.7.0: 1000 (InternalError: too much recursion)
on Windows XP SP3:
- Internet Explorer 6.0.2900.5512 SP3: 2541 (Error: Out of stack space)
- Internet Explorer 7.0.5730.13: 2555 (Error: Out of stack space)
- Internet Explorer 8.0.6001.18702: 3076 (Error: Out of stack space)
- Firefox 2.0.0.20: 1000 (InternalError: too much recursion)
- Firefox 3.0.10: 3000 (InternalError: too much recursion)
- Firefox 3.5 Beta 4: 3000 (InternalError: too much recursion)
- Chrome 1.0.154.65: 21837 (name: RangeError, type: stack_overflow)
- Safari 4 Public Beta (528.16): 43688 (RangeError: Maximum call stack size exceeded)
- Opera 9.64: Abort (control stack overflow). Script terminated.
Marcel Duran on May 19th, 2009 at 10:34 am
Marcel, thanks for the extra information!
Nicholas C. Zakas on May 19th, 2009 at 10:20 pm
[...] Posted on June 14th, 2009 in 他山之石 by lifesinger JavaScript stack overflow error | NCZOnline. [...]
JavaScript stack overflow error | NCZOnline - 岿œˆå¦‚æŒ on June 14th, 2009 at 9:24 am
[...] Zakas has blogged about some browsers limitations and recently ran some tests in order to check browsers call stack sizes.Not surprisingly, different browsers have different call stack sizes. Also not surprisingly, the [...]
Limitation on call stacks | JavaScript Rules on August 16th, 2009 at 10:09 pm
Kudos for the very cogent discussion.
I bumped my head on this particular ceiling while developing a “chainsaw” app to pull keywords from a BUNCH of sites for SEO analysis. The app is NOT out-of-control, i.e., this is not the result of poor programming or some anti-pattern; it’s simply a browser-based app that recurses a LOT, but silly, old Firefox (STILL my browser of choice) thinks it’s “saving me.” I can code around it now that I know (THANKS!! to you) the true nature of the underlying limit. It astounds me how much silly, pointless, WRONG chatter there is about this issue (when Google-d by error message) on the W(ild-’n')W(acky-)W(eb).
Again, thanks for offering REAL insight.
richarduie on August 23rd, 2009 at 9:56 am
Apparently this error also occurs when using bilateral references.
for example:
var someObject = {
}
var someOtherObject = {
otherObject: someObject
}
someObject.otherObject = someOtherObject;
At least it does so in opera as i ran over it there
Maggun on December 27th, 2009 at 2:10 pm
Comments are automatically closed after 14 days.