Search code examples
javascriptnode.jsecmascript-6promisees6-promise

How can I pass an error on a multiple promise?


So basically I am trying to create an Error handler by passing an error value which in my case is a number for a status code like 400, 500, etc. Now the problem is when the catch catches the error, which contains a value of the status code returned from the previous promise. When I log the value it logs the value correctly, but when I reject it and pass the value so it will be caught on the next promise's catch, it says that the value is undefined.

Here's the error code:

UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined

JS:

const findFromModel = async (model, query) => {
    return new Promise((resolve, reject) => {
        model = model instanceof Object ? model : {};
        if (model) {
            model.findOne(query, (err, obj) => {
                if (obj) {
                    resolve(obj);
                } else {
                    reject(400);
                }
            });
        } else {
            reject(400);
        }
    });
}

const makeOrder = async (title, body, userQuery) => {
    return new Promise((resolve, reject) => {
        title = (typeof title === 'string' && title.length > 0) ? title : '';
        body = (typeof body === 'string' && body.length > 0) ? body : '';
        if (title && body) {
            findFromModel(userModel, userQuery)
                .then(user => resolve(user))
                .catch(err => {
                    console.log(err); // logs 400
                    reject(err); // Undefined
                });
         } else {
             reject(400);
         }
    });
}

Execute the promise:

makeOrder('test', 'this is body', {id: 'test'})
    .then(obj => res.send(obj))
    .catch(err => res.sendStatus(err.message));

I just move from es5 to es6, so if you got any better ideas to improve my code, that will be hugely appreciated.


Solution

  • if you want to use async function, you can reduce your code more.

    Promise error would becomes exceptions so use try...catch to deal with it.

    Return from async function is effectively resolve the promise, throw an error is effectively reject it. (just like they're in Promise)

    const makeOrder = async (title, body, userQuery) => {
      title = (typeof title === 'string' && title.length > 0) ? title : '';
      body = (typeof body === 'string' && body.length > 0) ? body : '';
      if (title && body) {
        try{
          let user = await findFromModel(userModel, userQuery)
          return user
        }catch(err){
          console.log(err); // logs 400
          throw err;
        }
        throw 400;
      }
    }
    

    even if you want to use the old ways, it's commonly done with

    return findFromModel(userModel, userQuery)
       .catch(err => {console.log(err); throw err;});