0

I've have the same question as earlier but having trouble relating the answers to my code. Here's my error: RangeError: Maximum call stack size exceeded.

The highly simplified pseudo version of my code is this:

function make_request(url, other_params){ 

  request(url, function(response){

    if(something) var some_var = 'some value';
    else var some_var = '';

    //do something with response to generate, some_var, and insert into DB

    var my_arr = [some_var];

    connection.query('INSERT my_table SET name = ?', my_arr, function(err, rows, fields) {
         if(my_arr==''){
               // generate new url to make new request
               make_request(url, other_params);
         }
    });

  });
}

connection.query('SELECT * from my_table', function(err, rows, fields){

  var len =rows.length;

  for(var i = 0; i < len; i++){

    var url = rows[i].url;

    make_request(url, other_params);

  }     
});

I've tried wrapping the internal make_request in setImmediate or setTimeout amongst a few other hacks, but nothing seems to prevent the call stack error. I'm able to add any library that would make this work. Any thoughts would be appreciated.

Community
  • 1
  • 1
tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • There is too much pseudo code in here to see what's really going on. We need to see the REAL code. As you have the code in your question, it hardly does anything because `if(my_arr=='')` will never by true so the code makes a few DB queries and never does anything with the results. Nothing to see here so far. I don't think this code would generate your error. There's more to it than you show here. – jfriend00 Jul 30 '16 at 00:57
  • Jfriend00 my_arr=='' will be true 50% of the time. Is that helpful? – tim peterson Jul 30 '16 at 00:59
  • My code is super long but it's basically one function involving a http request which often gets called inside itself. Isn't there a generalizable solution to that? – tim peterson Jul 30 '16 at 01:00
  • 1
    We can't guess where the problem is. We have to see the actual code that causes the problem. As best I can see, the problem causing code is NOT in your question. Delete your question or show more REAL code so we can actually help you. You aren't likely to get many people to help you by asking us to make wild guesses and chat about them. – jfriend00 Jul 30 '16 at 01:01
  • 1
    You can call recursively from async responses without any worry of stack overflow. If you are calling recursively from synchronous code, then you run a risk of stack overflow if you do it too much. In both cases, you have to handle all errors appropriately (to avoid infinite looping or stack overflow) and make sure you fully understand how the recursion will properly terminate in all cases. Further advice on your specific problem needs to see the problem causing code. – jfriend00 Jul 30 '16 at 01:05
  • Hey @jfriend00, terminating the recursion in all cases is what I don't understand how to do. I'm making a gist out of my code, please hold on.... – tim peterson Jul 30 '16 at 01:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118679/discussion-between-tim-peterson-and-jfriend00). – tim peterson Jul 30 '16 at 01:15
  • You stop recursion by just returning from the function without calling itself again. In some cases (depending upon what your code does), you may also return a value that the caller checks to know that the recursion is done now, but usually, you just return and the chain unwinds. – jfriend00 Jul 30 '16 at 02:57
  • so `return;`? or `return true;` or `return false;` or `return 37;` Does it matter? – tim peterson Jul 30 '16 at 03:05
  • This is just a regular programming concept. What you return matters if the caller is looking at the return value or needs to look at the return value to know what to do next. A return value is used to communicate back some returned result. What value you return (if anything) depends entirely upon your code and what you are trying to do. – jfriend00 Jul 30 '16 at 03:13

2 Answers2

1

If I'm reading the code correctly, the block

     if(my_arr==''){
           // generate new url to make new request
           function make_request(url, other_params);
     }

Redefines make_request to be a null function. Don't you want to call it an this point, instead? I think that the null redefinition would leave you with an indirect recursion that has no way to terminate.

Prune
  • 76,765
  • 14
  • 60
  • 81
1

Try change your code

function make_request(url, other_params, callback){ // all async function mast have callback 
    // Hmmm...
    // request(url, function(response){ 
    request(url, function(err, response){  // according by doc - https://github.com/request/request
        // Use short notation
        var some_var = (smth) ? 'some-value' : '';

        // do-smth. Mayby problem is here?

        var my_arr = [some_var];
        connection.query('INSERT my_table SET name = ?', my_arr, function(err, rows, fields) {
            // Always check error
            if(err)
                return callback(err);

            // I don't understand what is it. If some_var == '' then my_arr == [], not ''
            // In any case this check must do on upper level
            /*
            if(my_arr=='')
                make_request(url, other_params);
            */
            callback(null, rows); // return data    
        });
    });
}


var async = require('async');

connection.query('SELECT url from my_table', function(err, rows, fields){ // if you need one field then don't request all
    // I repeat: Always check error. SQL can be correct, but db is busy.
    if (err)
        return console.log(err.message); 

    async.mapSeries(rows, make_request, function(err, results) {
        if (err)
            return console.log(err);

        // do smth with results 
        console.log(results);   
    });      
});

P.S. heinob in prev your question make very good answer.

Aikon Mogwai
  • 4,954
  • 2
  • 18
  • 31