0

When the following code is run:

(function recur() {
    recur()
})()

the following error is raised —

Uncaught RangeError: Maximum call stack size exceeded

— with the stack filled with references to the function (recur).

So why does the following code:

(function recur() {
    try {
        recur()
     } catch (error) {
        recur()
     }
})()

even though the error is caught in the try block, not return the error in the catch block? Or at least complain about the function overflowing the call stack?

When the code is run, it does pause all other non-asynchronous code from executing, but still... no errors?! What's going on here?


EDIT:

This behavior is especially weird with code like this:

(function notRecur() {
    try {
        Symbol() + 2
    } catch (error) {
        Symbol() + 2
    }
})()

that returns a TypeError when executed.

Just another question to experiment with, thanks for reading through and replying.

5
  • 1
    For every RangeError that could get thrown, you create a new catch handler. If you're handling every RangeError, where do you expect an unhandled RangeError to come from? Commented Sep 3, 2018 at 20:23
  • I'm still a bit lost. What I figured would happen is that the RangeError would get thrown in the catch handler preventing the script from calling the recur function again. Commented Sep 3, 2018 at 20:29
  • Possibly stackoverflow.com/questions/6095530/… will help Commented Sep 3, 2018 at 20:30
  • 1
    The RangeError is thrown in the try block and caught in the catch block. Once you've caught the RangeError, it's like it never happened. Then, in your catch block, you call recur again. This time around, you create a whole new catch block to handle the next RangeError that occurs, etc, etc. You have tonnes of these catch handlers due to the recursion - not many of them will actually see a RangeError occur, but when they do, they squash it and continue on with the recursion. Commented Sep 3, 2018 at 20:31
  • 3
    RE your edit - that's entirely different. For that, just run Symbol() + 2 completely standalone and you'll get a TypeError. There's no recursion involved here - so the error occurs in the try and is then handled in the catch. In your catch, you generate the same error but there's no catch for this as there's no recursive creation of catch handlers. Commented Sep 3, 2018 at 20:36

2 Answers 2

2

If you got endless recursion, the call stack gets filled up until it reaches a memory limit and crashes, in that case the error bubbles up and unwinds the stack:

 call > call > call > call > call > | memory limit
    <----------------------------- error

Now you directly catch that and retry:

 call > call > call > call > call  | memory limit
                           < error |
                           > call  |
                           < error |
                           > call  |
                           < error |
                           > call  |
                           ...

Although it looks very strange it doesnt fill up memory. However it blocks the browsers thread, so the browser might kill the whole thread after some time.

Sign up to request clarification or add additional context in comments.

Comments

2

You're getting an infinite loop of catched RangeError exceptions.

It will execute the recur call within the try block until the maximum call stack size is exceeded. Thereafter the catch block will be executed the first time and call recur again - leading to a RangeError exception - that's caught in the catch block - and so on.

To help visualize this, you can print the stack trace in your catch block before starting the recursion:

(function recur() {
    try {
        recur()
     } catch (error) {
        console.log(error.stack);
        recur()
     }
})()

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.