9

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?

mbilyanov
  • 2,315
  • 4
  • 29
  • 49

4 Answers4

14

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.

Frank Modica
  • 10,238
  • 3
  • 23
  • 39
4

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)

skyboyer
  • 22,209
  • 7
  • 57
  • 64
2

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');
  });
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
2

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()
});
}
gaaaaaa
  • 336
  • 1
  • 14