1

Let's imagine I've got 2 awaits in a for loop, how can I make sure the first one is completed without throwing an error before executing the second await and thus looping again. I tried doing this using Puppeteer but it keeps looping even if the promise is not resolved...

for(var i = 0; i < 20; i++){
        console.log('loop started')
    await page1.goto('https://www.residentadvisor.net/dj.aspx?country=01').catch((err) =>{
        console.log('Page load fail : '+ err)
        if (err == 'Error: net::ERR_INTERNET_DISCONNECTED' || err == 'Error: net::ERR_NETWORK_CHANGED' || err == 'Error: net::ERR_NAME_NOT_RESOLVED'){
        let refreshIntervalId = setInterval(() =>{
           handleConnexionError(refreshIntervalId,page1)
        }, 5000) 
    }
    })
    console.log('Page loaded : ' + i)
    let teub = await page1.evaluate(() =>{
        return document.querySelector('a').innerText
    })
    console.log('Evaluate done : ' + teub )
    }



async function handleConnexionError(refreshIntervalId,page1){
    console.log('Retrying to connect')
    let errorHandle = true
    await page1.goto('https://www.residentadvisor.net/dj.aspx?country=01').catch(() => {
        errorHandle = false
    })
    if (errorHandle) {
        console.log('Succesfully Reconnected')
        clearInterval(refreshIntervalId)
        return true
    }
    else {
        console.log('Connection Fail Retrying in 10 sec ...')
    }
}
5
  • No, it does not keep looping when the promise is not resolved. The second part will wait until the first awaited promise is fulfilled. Commented Feb 7, 2018 at 0:08
  • Did you mean not to handle the error and continue? Commented Feb 7, 2018 at 0:09
  • What is handleConnexionError? Show it. Also, you probably want a try/catch around the await page1.goto() part instead of a .catch(). Commented Feb 7, 2018 at 11:06
  • @acdcjunior I fixed it ! Commented Feb 8, 2018 at 16:28
  • You could use Bluebird Promise.reflect for this Commented Feb 8, 2018 at 17:00

1 Answer 1

1

You can create a new function and call it recursively on error.

/**
 * checks if error matches
 * @param {Object} err thrown error
 * @return {Boolean}
 */
async function shouldRetry(err) {
    return [
        "Error: net::ERR_INTERNET_DISCONNECTED",
        "Error: net::ERR_NETWORK_CHANGED",
        "Error: net::ERR_NAME_NOT_RESOLVED"
    ].includes(err);
}

/**
 * Function to Re navigate endlessly on error
 * @param {Object} config
 * @param {string} config.page the page instance
 * @param {String} config.url url to browse
 * @param {Number} config.delay delay for retry
 * @return {Promise}
 */
async function navigateUrl({ page, url, delay }) {
    try {
        // wait for page load
        const response = await page.goto(url);
        return response;
    } catch (error) {
        if (shouldRetry(error)) {
            // use a delay promise or the built in waitFor function
            await page.waitFor(delay);
            // re navigate
            return navigateUrl({ page, url, delay });
        } else {
            // throw on other errors
            throw new Error(error);
        }
    }
}

// now you can use them however you want
await navigateUrl({ page, 'http://example.com', 2000 });
await page.evaluate(() =>{
    return document.querySelector('a').innerText
});

It's best if you can keep things seperate, easier to write and maintain.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.