0

I have a promise chain that is currently running with very basic error handling. If a step fails, the subsequent steps will not run. I want to be able to continue the promise chain at a later time if there is a failure, and it should start from where it left off.

This is what my current code looks like:

// controller.js
var failure = false;
QueryFactory.step1()                      // Step 1
   .then(function(msg){
      if(failure == false){
        console.log("Finished Step 1");
        return QueryFactory.step2();
      }
   }, function(err){
      console.log(err);
      failure = true;
   })
   .then(function(msg){                   // Step 2
      if(failure == false){
         console.log("Finished Step 2");
         return QueryFactory.step3();
      }
   }, function(err){
      console.log(err);
      failure = true;
   })
   .then(function(msg){                   // Step 3
      if(failure == false){
         console.log("Finished Step 3");
      }
   }, function(err){
      console.log(err);
      failure = true;
   })

And my factory looks like this:

// QueryFactory.js
step1 = function(){
   var deferred = $q.defer();
   $http.post('/task', {step_num: 1})
      .then(function(data)){
         deferred.resolve(data);
      }, function(err){
         deferred.reject(err);
      });
   return deferred.promise;
}
// step2 and step3 are similar

But perhaps there is a better way of writing this to allow for modularity? Say step2 were to fail, how can I design a way so that a user can click a button to later continue the chain from step2?

3
  • Your "chain" doesn't pass any data from any step to the following step. Also, they will all execute one after the other, regardless of "success" or "failure". Commented Apr 13, 2016 at 18:09
  • So how do you recommend I do this correctly? Commented Apr 13, 2016 at 18:13
  • 1
    First of all, avoid the deferred antipattern! Commented Apr 13, 2016 at 18:21

1 Answer 1

1

Have a look at the difference between .then(…).catch(…) and .then(…, …). In your case, by passing the second callback to then, you'd eventually step over the current step instead of continuing where you left off. What you are looking for is

QueryFactory.step1()
.then(function(msg) {
    console.log("Finished Step 1 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function() {
    return QueryFactory.step2();
}).then(function(msg) {
    console.log("Finished Step 2 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function() {
    return QueryFactory.step3();
}).then(function(msg) {
    console.log("Finished Step 3 without error");
    return msg;
}, function(err) {
    console.log(err);
    …
}).then(function(res) {
    console.log("everything is finished");
}).catch(function(err){
    console.error("something bad happened", err);
});

(Alternatively you can use a plain .catch instead of the then with the callback that tells you whether a step finished without error, if you don't need those logs)

Now, what are these in the code? It's for your requirement

I want to be able to continue the promise chain at a later time if there is a failure

In the sections, you will need to handle the error, and return a promise for error-free result of the step that failed, e.g. by retrying. This promise would only settle at that "later time" - you can wait for a user confirmation of the error, a timeout, or whatever you want.

Once that promise you returned from the error callback settles, the chain will continue.

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.