0

I have an asynchronous function in Node.js I am calling over and over again. It basically fetches some data from API, processes it and this repeats forever. I have wrapped the whole function inside a try catch block with a finally statement, which calls the function again.

It looks like this:

async function infiniteLoop()
{
    try
    {
        console.log(Date.now())
        const response = await axios.get(...) // fetch data

        await Promise.all(response.data.entities.map(async (entity) => 
        {
            const product = new Product(entity)
            await product.resolve()
        }))
    }
    catch (e)
    {
        console.error(e)
    }
    finally
    {
        setTimeout(() => infiniteLoop(), 1000)
    }
}

The thing is that this infinite loop is sometimes broken and I have no reason why. By breaking I mean that the function is no longer doing anything. I was thinking it may be stuck somewhere, but I am using only axios (with timeout set to 5000 ms) and prisma. Nothing is printed out to console in the catch block etc. The Node process does not ever crash if the infinite loop breaks.

The infinite loop breaks randomly. Sometimes it breaks after several hours, sometimes after few days.

zzmichalqq
  • 105
  • 1
  • 10
  • 1
    share your axios.get(...) code as well . `console.error()` writes to stderr, whereas `console.log()` writes to stdout as described in the official docs [ https://nodejs.org/api/console.html#console_console_error_data_args ] In a default run of nodejs, both `stdout` and `stderr` go to the console, but obviously, they could be directed in different places that you need to check. – Deep Kakkar Nov 30 '21 at 12:37
  • I added the code. – zzmichalqq Nov 30 '21 at 12:43
  • Where are you calling infiniteLoop() initially ? i.e. initial call for the function, as finally is in the function. – Deep Kakkar Nov 30 '21 at 12:44
  • In an anonymous async function. `(async () => { await infiniteLoop() })();` – zzmichalqq Nov 30 '21 at 12:46
  • Maybe 429(too many requests)? – Tiko Nov 30 '21 at 12:48

3 Answers3

0

I believe it should be an issue in the API, like 429 API response etc.
console.error() writes to stderr, whereas console.log() writes to stdout as described in the official docs .

In a default run of Nodejs, both stdout and stderr go to the console of browser, but obviously, they could be directed in different places that you need to check.

Here below is a working example without API call.

function infiniteLoop()
{
    try
    {
        console.log(Date.now())
        
    }
    catch (e)
    {
        console.error(e)
    }
    finally
    {
        setTimeout(() => infiniteLoop(), 1000)
    }
}
infiniteLoop();
Deep Kakkar
  • 5,831
  • 4
  • 39
  • 75
  • I am not exactly sure what do you mean by "they could be directed in different places". Sometimes I get errors printed in the catch block, but the function is still running over and over again. It just stops all of sudden with no error. I was wondering maybe some of my promises may be hanging, thus the code is stuck at Promise.all? – zzmichalqq Nov 30 '21 at 12:54
  • Function will run on each second as you are using setTimeOut with 1000 . I believe it is an error from API , as you are calling API on each second from API. So it should be either 429 or 500 – Deep Kakkar Nov 30 '21 at 12:57
  • Sometimes I receive errors in the catch block, they are properly printed and the infinite loop continues as it should, cause the finally block is called anyway. For example the last time I received error at 20:00 and the function stopped working at around 22:30. The finally block should only be called when the entire try block is completed, so I get proper "synchronous" loop. – zzmichalqq Nov 30 '21 at 12:58
0

Instead of a function calling itself over and over again you could do setInterval

This is a delayed infinite loop that in this example triggers every 1000 mills.

setInterval(async () => {
    // do stuff here
    
}, 1000);
1euro7cent
  • 47
  • 5
  • 1
    It doesn't simulate the scenario. A 1000ms gap is granted by `setTimeout`, but, `setInterval` does the task every 1000ms. – Raeisi Dec 01 '21 at 06:01
0

I was using wrong error handling in the catch block as described here: https://stackoverflow.com/a/33446005/14924239 I was using throw instead of reject.

zzmichalqq
  • 105
  • 1
  • 10