Andrey Radkevich
Andrey Radkevich

Reputation: 927

How to catch error from promise (node js)

let commandPromise = async (command) => {
    try {
        return new Promise((resolve, reject) => {
            try {
                child_process.exec(command, (error, stdout, stderr) => {
                    if (error) return reject(error);
                    if (stderr) return reject(stderr);
                    return resolve(stdout)
                })
            } catch (err) {
                return reject(err)
            }
        })
    } catch (err) {
        throw err
    }
};

Is it the correct way to catch the error in this case or exist better way? The code seems not good.

Upvotes: 0

Views: 4810

Answers (4)

Igor Litvinovich
Igor Litvinovich

Reputation: 2502

For your case everithing will work if you add 'await' before new Promise()

 let commandPromise = async (command) => {
   try {
       return await new Promise((resolve, reject) => {
           try {
               child_process.exec(command, (error, stdout, stderr) => {
                   if (error) return reject(error);
                   if (stderr) return reject(stderr);
                   return resolve(stdout)
               })
           } catch (err) {
               return reject(err)
           }
       })
   } catch (err) {
       throw err
   }
 };

Upvotes: 2

Jose Mato
Jose Mato

Reputation: 2799

You are missing concepts here but, this is the golden rule:

  • For sync code, use try / catch
  • For async code, avoid try / catch because doesn't work and go for callback(err, data) or Promise reject styl
  • If you are using new ES7 syntax await/sync then you can use try / catch

On your code, this is one simple approach:

const commandPromise = async (command) => {
  return new Promise((resolve, reject) => {
    child_process.exec(command, (error, stdout, stderr) => {
        if (error) {
          return reject(error);
        }

        if (stderr) {
          return reject(stderr);
        }

        return resolve(stdout)
    });
  });
};

ES7 way:

const commandPromise = async function(command) {  
  child_process.exec(command, (error, stdout, stderr) => {
      if (error) {
        throw error;
      }

      if (stderr) {
        throw stderr;
      }

      return stdout;
  });
};

Upvotes: 1

Anand Undavia
Anand Undavia

Reputation: 3543

Both of the try - catch blocks are unnecessary and you can get rid of them.
Moreover, because commandPromise does not use await keyword, you can also remove the async keyword from the function declaration.
Any errors occured during the execution of the child_process would be passed as error in the callback which your code already handles.

Here is the better code:

let commandPromise = (command) =>
    new Promise((resolve, reject) => {
        child_process.exec(command, (error, stdout, stderr) => {
            if (error) return reject(error);
            if (stderr) return reject(stderr);
            return resolve(stdout);
        });
    });

And to use it:

commandPromise(/* some command */)
    .then(() => {
        /* ok */
    })
    .catch((error) => {
        /* handle error */
    });

Upvotes: 1

tbking
tbking

Reputation: 9076

Errors thrown or rejected in promises can be caught by .catch() method. Try/catch doesn't work with asynchronous code.

You can use it like:

promise.catch(function(err) {
    // do something
})

For more details, look at other stackoverflow answers which target the same question.

Upvotes: 0

Related Questions