physicsboy
physicsboy

Reputation: 6316

JS Promises - Why am I seeing the UnhandledPromiseRejectionWarning and DeprecationWarning?

I am getting to grips with promises and how to set them up, however I can't see why node thinks my promise is unhandled when it comes to errors... Can somebody please explain?

My simple code

    // Setting up the Promise
    function add(x, y) {
        return new Promise((response, reject) => {
            // Simple conditional (not perfect, but it just proves a point)
            if(x !== null && y !== null) {
                // I know I could have done 'response(x + y)', but I wanted 
                // to console.log the result also
                var calc = x + y
                response(calc)
                console.log('Calculation: ' + x + ' + ' + y + ' = ' + calc)
            } else {
                // My console does not throw this error?
                reject('One of the inputs was null')
            }
        })
    }
    
    // Function using the Promise
    function calc() {
        add(1, 3)
            .then(res => add(res, 3))
            .then(res => add(res, null))
            .then(res => console.log('Final result: '+res))
            .catch(err => {
                // This error is thrown in console
                throw new Error('Something went horribly wrong')
            })
    }
    
    // Run the code
    calc();

Update

I originally posted the 'reject' with a thrown error, of which I understand needs to be caught.

I also want to understand why the string in the 'reject' is not seen in my console?

Console output:

Calculation: 1 + 3 = 4
Calculation: 4 + 3 = 7
(node:61950) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Something went horribly wrong
(node:61950) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Upvotes: 1

Views: 82

Answers (2)

Intervalia
Intervalia

Reputation: 10945

You are calling reject and throwing an error. You only need to do one of them.

You are not displaying the first error message.

It is also important to use .catch for any thrown error when you call add.

When you do this: throw new Error('Something went horribly wrong') you are still in a promise and if you don't catch it you are causing problems. In future versions of Node.js this will cause your application to exit with an error code. So you will need to make sure you always catch thrown errors within a promise.

Using Reject

// Setting up the Promise
function add(x, y) {
  return new Promise((response, reject) => {
    // Simple conditional (not perfect, but it just proves a point)
    if(x !== null && y !== null) {
      // I know I could have done 'response(x + y)', but I wanted 
      // to console.log the result also
      var calc = x + y
      response(calc)
      console.log('Calculation: ' + x + ' + ' + y + ' = ' + calc)
    } else {
      // My console does not throw this error?
      reject(new Error('One of the inputs was null'))
    }
  })
}

// Function using the Promise
function calc() {
  return add(1, 3)
    .then(res => add(res, 3))
    .then(res => add(res, null))
    .then(res => console.log('Final result: '+res))
    .catch(err => {
      console.error("Internal Error:", err.message);
      // This error is thrown in console
      throw new Error('Something went horribly wrong')
    })
}

// Run the code
calc().catch((err) => {
  console.error("Outer error:", err.message);
});

Using Throw:

// Setting up the Promise
function add(x, y) {
  return new Promise((response, reject) => {
    // Simple conditional (not perfect, but it just proves a point)
    if(x !== null && y !== null) {
      // I know I could have done 'response(x + y)', but I wanted 
      // to console.log the result also
      var calc = x + y
      response(calc)
      console.log('Calculation: ' + x + ' + ' + y + ' = ' + calc)
    } else {
      // My console does not throw this error?
      throw new Error('One of the inputs was null')
    }
  })
}

// Function using the Promise
function calc() {
  return add(1, 3)
    .then(res => add(res, 3))
    .then(res => add(res, null))
    .then(res => console.log('Final result: '+res))
    .catch(err => {
      console.error("Internal Error:", err.message);
      // This error is thrown in console
      throw new Error('Something went horribly wrong')
    })
}

// Run the code
calc().catch((err) => {
  console.error("Outer error:", err.message);
});

I added a return of the promise returned by add so you can catch the final error.

The other way to do it is to not throw the final error and handle it differently.

Upvotes: 1

Mouradif
Mouradif

Reputation: 2694

In your function using the Promise :

// Function using the Promise
function calc() {
    add(1, 3)
        .then(res => add(res, 3))
        .then(res => add(res, null))
        .then(res => console.log('Final result: '+res))
        .catch(err => {
            // This error is thrown in console
    --->    throw new Error('Something went horribly wrong')
        })
}

The line maked with ---> throws an Error. That error isn't caught. Usually when you catch an error you want to do something with it. If you throw it back or throw another error, that throw should be caught.

What I'd do with this is the following :

// Function using the Promise
function calc() {
    return add(1, 3)
        .then(res => add(res, 3))
        .then(res => add(res, null))
        .then(res => console.log('Final result: '+res))
        .catch(err => {
            // This error is thrown in console
            throw new Error('Something went horribly wrong')
        })
}

calc().catch(err => {
    console.log(error.message); // For example
});

Upvotes: 1

Related Questions