Looping a Promise

Viewed 89

What I want to do is everytime I get a no provider error is to redo the check and get the new Provider's section. So what I want to is encase a Promise inside a loop and then either leave when no provider works or leave when there are no errors on the page.

As I am unsure of how to use Promises inside loops I'm not sure where to go from this.

await driver.wait(until.elementLocated(By.xpath(path)), 5000, 'Timed out after 5 seconds', 500).then(found => {
    console.log("Found no provider error");
    // click back goes to same page different section
    // click new index for dropdown
    // return if index is not valid
    // then click next to go back to same section.

}, error => {
    console.log("Didn't find no provider error")

});

I tried using the following

retry(_ =>
            driver.wait(until.elementLocated(By.xpath(path)),5000)
              .then(found => {
                  
                console.log("Provider error");
                throw Error("Provider error");
                
              }, error=>{
                console.log("Didn't find no provider error");
                
                return;
                
                
              })
            , providerDropDownCount
        )
        .then(result =>console.log(result))
        .catch(err => console.error("Failed after ", err)) 

Which leads to no repeats.

Provider error
Failed after  Error: Provider error
    at C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\index.js:255:23
    at processTicksAndRejections (node:internal/process/task_queues:93:5)
    at async retry (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\index.js:221:14)
1 Answers

You can write a retry function that takes a task and a count of retry attempts -

async function retry (task, count) {
  try {
    return await task()
  }
  catch (err) {
    if (count <= 0)
      throw err
    else
      return retry(task, count - 1)
  }
}

In your .then handler, you can throw and error that will cause the task to be retried

retry(_ =>
  driver
    .wait(...)
    .then(found => {
       if (someCondition)
         throw Error("could not find...")
       else
         return found
    })
  , 5
)
.then(result => ...)
.catch(err => console.error("failed after 5 retries", err))

Here is retry in action. Run the snippet several times to see the various behaviours -

async function retry (task, count) {
  try {
    return await task()
  }
  catch (err) {
    if (count <= 0)
      throw err
    else
      return retry(task, count - 1)
  }
}

async function someTask () {
  console.log("running task")
  await new Promise(r => setTimeout(r, 1000))
  const num = Math.random()
  if (num > .9)
    return num
  else
    throw Error("something bad happened")
}

retry(someTask, 5)
  .then(console.log, console.error)

Related