Search code examples
node.jses6-promise

Promises best practice: Promise.resolve(false) or Promise.reject()?


I have a function exists that checks somethings and returns a promise, and a function isAuthorized that calls it. I can use it via two ways:

// Way A: resolve() or reject()

export const existsA = (id) => {
    return getSomethingById(id)
        .then((result) => {
            if (!result ) {
                return Promise.reject(new Error(''));
            }

            return Promise.resolve();
        })
        .catch(error => Promise.reject(new Error(error)));
};

exports.isAuthorizedA = (req, res, next) => {
    existsA(req.user.id)
        .then(next)
        .catch(next(Boom.forbidden()));
};

// Way B: resolve(true) or resolve(false)

export const existsB = (id) => {
    return getSomethingById(id)
        .then((result) => {
            if (!result ) {
                return Promise.resolve(false);
            }

            return Promise.resolve(true);
        })
        .catch(error => Promise.reject(new Error(error)));
};

exports.isAuthorizedB = (req, res, next) => {
    existsB(req.user.id)
        .then((result) => (result ? next() : next(Boom.forbidden())))
        .catch(next(Boom.forbidden()));
};

Which way is correct ? Thank you by advance.


Solution

  • Best practice is to reject the promise of any error occurrence(uncaught exceptions) so better would be

    const existsA = (id) => getSomethingById(id);
    
    const isAuthorizedA = (req, res, next) => {
        existsA(req.user.id)
            .then(next)
            .catch(next(Boom.forbidden()));
    };
    

    handle all your fail case in getSomethingById() and reject the errors from there. If you want null or any falsy value as error then write

    getSomethingById(id) => {
      new Promise(function(resolve, reject) {
      // your operations    
      if(!value)
        reject(new Error('your code'))
      else
        resolve(123)
    });
    

    as for your use case you don't want a false as a result, I mean sometimes in your promise you expect a false as a positive result like following

    checkIfPostIsLiked(userId, postId)
    .then(isLiked => {
        if (isLiked) return unLikePost(userId, postId)
        return likePost(userId, postId)
    })
    .catch(next(Boom.forbidden()));
    

    If you are considering false as an error then this might not work.

    So as a best practice whenever you want to throw an error or mark that case as a fail case then always reject promise and handle it in the catch block.