javascriptnode.jserror-handlingpromisethrow

Using throw in promises


I would like to create a function that returns a promise and if something throws an error within, it returns promise reject.

function promiseFunc(options) {
  return new Promise(() => {
    return options;
  });
}

function myfunc(options) {
  return new Promise(() => {
    if (!options) throw new Error("missing options");

    return promiseFunc(options).then((result) => {
      if (result.throwerr) throw new Error("thrown on purpose");

      return result.value;
    });
  });
};

My test as follows:

const myfunc = require("./myfunc");

describe('myfunc', () => {
  it('should fail without options', () => {
    return myfunc()
      .then((result) => { throw new Error(result) }, (err) => {
        console.log("test #1 result:", err.message === "missing options");
      });
  });

  it('should fail on options.throwerr', () => {
    return myfunc({throwerr: true})
      .then((result) => {}, (err) => {
        console.log("test #2 result:", err.message === "thrown on purpose");
      });
  });

  it('should return options.value', () => {
    return myfunc({value: "some result", throwerr: false})
      .then((result) => {
        console.log("test #3 result:", result === "some result");
      }, (err) => {});
  });
});

The first test pass, but the second and third fails.

Log #2 does not even run, so I assumed the "throw on purpose" messes up something, therefore I created test #3, where I don't throw anything, but it still fails. What am I missing?

Solution:

function promiseFunc(options) {
  return new Promise(resolve => {
    return resolve(options);
  });
}

function myfunc(options) {
  return new Promise((resolve, reject) => {
    if (!options) throw new Error("missing options");

    return promiseFunc(options).then(result => {
      if (result.throwerr) throw new Error("thrown on purpose");

      return resolve(result.value);
    }).catch(err => {
      return reject(err);
    });
  });
};

Solution

  • You forgot to pass a function with resolve and reject parameters, so your promises just don't work.

    function promiseFunc(options) {
      return new Promise(resolve => { // resolve function
        resolve(options)
      })
    }
    
    module.exports = function myfunc(options) {
      return new Promise((resolve, reject) => { // since you may either resolve your promise or reject it, you need two params
        if (!options) {
          return reject(new Error("missing options"))
        }
    
        return promiseFunc(options).then(result => {
          if (result.throwerr) {
            return reject(new Error("thrown on purpose"))
          }
          resolve(result.value)
        })
      })
    }
    

    ... and the test (mocha)

    const assert = require('assert'),
          myfunc = require("./myfunc")
    
    describe('myfunc', () => {
      it('should fail without options', done => { // mind the callback, promises are always async
        myfunc()
          .catch(err => {
            assert(err.message === "missing options")
            done() // <- called here
          })
      })
    
       it('should fail on options.throwerr', done => {
          myfunc({throwerr: true})
             .catch(err => {
                assert(err.message === "thrown on purpose")
                done()
          })
       })
    
      it('should return options.value', done => {
        return myfunc({value: "some result", throwerr: false})
          .then(result => {
              assert(result === "some result")
              done()
           })
        })
     })