ArshSoni
ArshSoni

Reputation: 147

Break promise chain - stop the next 'then' from executing

I am writing a registration system in Node/Express and I am trying to make use of Promises.

The issue is that I get an error message when using them:

Error:

(node:64725) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2):

Is there a way to stop at a then?

auth.isRegistered(email)
.then((registered) => {
    if ( !registered ) {
        req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.');
        req.session.user = user;
        res.redirect('/register')
    }
})
.then(() => {
    return auth.isVerified(email);
})
.then((verified) => {
    if ( !verified ) {
        console.log('please verify');
        res.redirect('/register/verify');
    } else {
        req.login(user, err => {
            if ( err ) return next(err);
            req.session.timestamp = Date.now();
            auth.updateLastLogin(email)
            .then(() => {
                res.redirect(req.session.returnTo || '/account');
            });
        });
    }
});

Upvotes: 4

Views: 9802

Answers (3)

Sajid2405
Sajid2405

Reputation: 318

Language: JavaScript

For simplicity just use:- (in case you don't want to further process the error)

throw new Error("An error occured");

Example:- (fetch)

fetch("endpoint/resource", requestOptions)
        .then(response => {
            if(response != null && response.status == 404) {
                throw new Error("RECEIVED NULL OBJECT");
            }
            return response;
        })
        .then(approvedResponse => approvedResponse.blob())
.catch(e => console.log(e));

Upvotes: 1

alexmac
alexmac

Reputation: 19617

You can do the following:

  1. Throw a custom error, when you want to break the promise chain.
  2. Check in catch callback that thrown error is a custom error. If so, just continue, otherwise call next with error object:

Example:

let getBreackChainError = () => {
  let err = new Error();
  err.name = 'BreackChainError';
  return err;
};

auth
  .isRegistered(email)
  .then(registered => {
      if (!registered) {
        req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.');
        req.session.user = user;
        res.redirect('/register');
        throw getBreackChainError();
      }
      return auth.isVerified(email);
  })
  .then(verified => {
      if (!verified) {
        console.log('please verify');
        res.redirect('/register/verify');
        throw getBreackChainError();
      }
      return new Promise((resolve, reject) => {
        req.login(user, err => {
          if (err) {
            return reject(err);
          }
          req.session.timestamp = Date.now();
          resolve();
        });
      });
  })
  .then(() => auth.updateLastLogin(email))
  .then(() => res.redirect(req.session.returnTo || '/account');
  .catch(err => {
    if (err.name !== 'BreackChainError') {
      next(err);
    }
  });

Note. You shouldn't mix callbacks with promises, use something one. In the example above, I promisified req.login, so now it returns a promise.

Upvotes: 4

Hunter
Hunter

Reputation: 416

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): I believe this is because you do not have a way to handle the error in your initial .thens, because of this you get the above error. Its not "stopping" the .then, but handling the error correctly. you could do (err)=> {return} which would essentially "stop" it but its flow control in your application.

Upvotes: -1

Related Questions