Search code examples
javascriptasync-awaittry-catches6-promise

Code throwing unhandled rejection error when running promise


I am trying to write a Javascript promise that resolves and rejects the desired variables. I am getting the error message below after running in the console

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().
 code: 'ERR_UNHANDLED_REJECTION'

Here is my code

Js File:


const grimeUserLeft = false;
const userWatchingGrimeVids = true;

let grimePromise = new Promise((resolve, reject) => {
  if (grimeUserLeft) {
    reject("User Left");
  } else if (userWatchingGrimeVids) {
    reject("This user is a G");
  } else {
    resolve("Congrats. Your channel doesn't suck");
  }
});

grimePromise.then((message) => {
  console.log("Success: " + message);
});
grimePromise.catch((message) => {
  console.log("You Failed: " + message);
});


Solution

  • By calling the .then() and the .catch() handler on two different places, you actually end up with two different promises - each of .then() and .catch() returns a new one. The promise returned by .then() will not be caught by the separate .catch() handler:

    const grimeUserLeft = false;
    const userWatchingGrimeVids = true;
    
    let grimePromise = new Promise((resolve, reject) => {
      if (grimeUserLeft) {
        reject("User Left");
      } else if (userWatchingGrimeVids) {
        reject("This user is a G");
      } else {
        resolve("Congrats. Your channel doesn't suck");
      }
    });
    
    grimePromise
      .then((message) => {
        console.log("Success: " + message);
      })
      .catch(() => console.log(1));
    
    grimePromise.catch((message) => {
      console.log(2);
      console.log("You Failed: " + message);
    });

    Therefore, one promise gets turned into two. Each of them will adopt the state of the original promise. When the original is rejected, both the derived promises reject. Yet only one is handled.

    Instead, you can directly specify the .catch() in the same promise chain as the .then():

    const grimeUserLeft = false;
    const userWatchingGrimeVids = true;
    
    let grimePromise = new Promise((resolve, reject) => {
      if (grimeUserLeft) {
        reject("User Left");
      } else if (userWatchingGrimeVids) {
        reject("This user is a G");
      } else {
        resolve("Congrats. Your channel doesn't suck");
      }
    });
    
    grimePromise
      .then((message) => {
        console.log("Success: " + message);
      })
      .catch((message) => {
        console.log("You Failed: " + message);
      });
    <h1>Check the browser console - no unhandled promise rejections</h1>

    Or alternatively, specify both handlers in the then():

    const grimeUserLeft = false;
    const userWatchingGrimeVids = true;
    
    let grimePromise = new Promise((resolve, reject) => {
      if (grimeUserLeft) {
        reject("User Left");
      } else if (userWatchingGrimeVids) {
        reject("This user is a G");
      } else {
        resolve("Congrats. Your channel doesn't suck");
      }
    });
    
    grimePromise
      .then(
        (message) => {
          console.log("Success: " + message);
        },
        (message) => {
          console.log("You Failed: " + message);
        }
      );
    <h1>Check the browser console - no unhandled promise rejections</h1>