Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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');
            });
        });
    }
});
like image 664
ArshSoni Avatar asked Sep 06 '25 15:09

ArshSoni


2 Answers

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.

like image 186
alexmac Avatar answered Sep 09 '25 04:09

alexmac


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));
like image 30
Sajid2405 Avatar answered Sep 09 '25 05:09

Sajid2405