mbilyanov
mbilyanov

Reputation: 2511

Retrying a failed async/promise function?

I have this async block:

test().then(function(result){
    // Success: Do something.
    doSomething();
}).catch(function(error){
    // Error: Handle the error, retry!
    // How to re-run this whole block?
});

I can keep track of the success and failed outcomes. However, is it possible to retry the whole test().then().catch() chain if we fail? And keep retrying until the condition resolves?

Upvotes: 8

Views: 14716

Answers (4)

skyboyer
skyboyer

Reputation: 23705

Assuming it's all about resending request to some buggy/bloat-up 3rd party API

If it's production question rather educational one I'd suggest search for 3rd party lib that implementing this on your own.

Say for axios there is nice axios-retry.

Why? Assume you may think there is just one case when API say returns 502. But actually there are much more cases it'd be better to keep in mind:

  1. differing particular error causes, say once there is Network or DNS Lookup Error there may be no need to repeat request
  2. retry count limitation
  3. increasing delay
  4. something else

Writing such a logic on your own would be real overkill. And trying to use simplest solution may hit you when you don't expect it.

PS also as a bonus you would be able to configure all requests to some specific API with single snippet like it goes for axios' custom instances(and I believe there should other plugins for alternative libraries)

Upvotes: 4

Frank Modica
Frank Modica

Reputation: 10516

If you can switch to async/await syntax, you can use a while loop:

let keepTrying;

do {
    try {
        await test();
        keepTrying = false;
    } catch {
        keepTrying = true;
    }
} while (keepTrying)

doSomething();

You could then abstract the retrying logic into its own function to be reused.

Upvotes: 16

gaaaaaa
gaaaaaa

Reputation: 366

You can put it in a function.

function dbug() {

test().then(function(result){
    // Success: Do something.
    doSomething();
}).catch(function(error){
    // Error: Handle the error, retry!
    dbug()
});
}

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370679

You could put the whole thing into a function that recursively calls itself if the catch block is entered:

function tryTest() {
  return test().then(function(result) {
    // Success: Do something.
    doSomething();
  }).catch(function(error) {
    // error handling

    // make sure to return here,
    // so that the initial call of tryTest can know when the whole operation was successful
    return tryTest();
  });
}


tryTest()
  .then(() => {
    console.log('Finished successfully');
  });

If your doSomething can take the result argument, and if tryTest doesn't take any arguments, you can simplify the above to:

function tryTest() {
  return test()
    .then(doSomething)
    .catch(tryTest);
}


tryTest()
  .then(() => {
    console.log('Finished successfully');
  });

Upvotes: 1

Related Questions