how to catch a “Maximum call stack size exceeded” error?

前端 未结 4 1237
走了就别回头了
走了就别回头了 2021-01-14 17:58
  try {
     requestAnimationFrame(function re(){
       re();
     })}
  catch (e){
       console.log(e);
     }

I tried above code in console, i

相关标签:
4条回答
  • 2021-01-14 18:06

    This can be certainly done. More than that – if you'll stick to a meaningful pattern, you can determine how many times your function had run before the call stack overflowed (I wouldn't dare to try it on a function that is recursively invoked, rather than returned, as in the original question, because in this case the call stack can get really funky):

    function doRecursionOrDieTryin(n = 0) {
        try {
        return doRecursionOrDieTryin(n + 1);
      } catch(err) {
        return `There was an exception: "${err}" when tryin' to make iteration no. ${n}`;
      }
    }
    
    doRecursionOrDieTryin()
    

    Warning: This function starts an infinite loop, so it could crash you browser if you will try to run this in a distant future, when the common JS engines will be fully tail-call-optimized. For 10/2018, it gots to iteration no. 10454 in Chrome 69. In Firefox 62 the limit of stack overfow is changing (from 10077 to 20989, then 22160), probably due to some kind of smart runtime optimization. Haven't test it yet in Edge.

    0 讨论(0)
  • 2021-01-14 18:17

    Maximum call stack size exceeded errors can be caught just like any other errors:

    try {
      function recur() { recur(); };
      recur();
    } catch (ex) {
      console.log("caught " + ex);
    }

    What to do in this situation (call stack size exceeded) is not defined in the ECMAScript specification, but in practice, all browsers do throw catchable exceptions. However, lacking a spec different browsers have chosen to throw different types of exceptions: I've seen Error, RangeError and InternalError.

    The problem in your code is unrelated to that. The problem is that you're trying to catch exceptions that happen when you call requestAnimationFrame(). But your re() function doesn't run at that point, it runs during the next frame, as you requested. Inside of re(), you can wrap the recursive call to re() and catch the stack overflow exception there instead:

    requestAnimationFrame(function re(){
      try {
        re();
      } catch (ex) {
        console.log("caught " + ex);
      }
    });

    0 讨论(0)
  • 2021-01-14 18:24

    the thing about catching a maximum stack size exceeded error is I'm not sure how it would work. The only thing that the browser could do to allow the error to be caught is empty the stack then have the next function run be the catch function but at that point (and I don't think browsers can even get it that far) you would have no indication on where your code broke so anything you tried to run would be severely buggy at best.

    Another problem (which is probably why no browsers have this) is because most functions you would run after the error would simply try to restart normal web function in some way. Since you don't know what broke you can't stop it from happening again so you would end up crashing it again and again. Which would make both the users and the browsers mad at your web page.

    So I guess the best that can be done is make sure your code doesn't have infinity loops and is able to run smoothly

    a good description of stack size and how it works can be found in the answer to this question

    0 讨论(0)
  • 2021-01-14 18:27

    You are calling the same function within the function re() inside your requestAnimationFrame() function. A correct way would be as follows:

    function re(){
        //code here
        requestAnimationFrame(re); //loop back to start
    }
    
    0 讨论(0)
提交回复
热议问题