1
votes

If there is a promise with an asynchronous function in it and if in the asynchronous function an error happens the promise doesn't catch but throws an error and crashes the application, which I don't understand.

Obviously I would like to handle the error, do you know why does the promise behave like this and what would be a way around it?

thanks

// this promise will have an error since param is not defined,
// and the promise won't be caught
function randomPromise(param) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            param[0] = 11;
        }, 2000);
    });
}

randomPromise()
.then(() => {
    console.log('nothing');
})
.catch((e) => {
    console.log('with set timeout or any async function in the promise, the error caused by \'param[0] = 11;\' wont bring the control here into the catch block just throws an error and crashes the application');
    console.log(e);
});

// this promise will have an error since param is not defined
// but the promise will be caught
function randomPromiseGoesToCatchBlock(param) {
    return new Promise((resolve, reject) => {
        param[0] = 11;
    });
}

randomPromiseGoesToCatchBlock()
.then(() => {
    console.log('nothing');
})
.catch((e) => {
    console.log('without the setTimeout function or any async function the error caused by \'param[0] = 11;\' brings the control here into the catch block');
    console.log(e);
});
1

1 Answers

4
votes

Errors that are thrown inside a Promise constructor and that occur asynchronously need to be explicitly try/catched so that reject can be called, so that the Promise control flow can be transferred to the Promise's catch. For example:

// this promise will have an error since param is not defined, and the promise wont be catched
function randomPromise(param) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      try {
        param[0] = 11;
      } catch(e) {
        reject(e);
      }
    }, 2000);
  });
}

randomPromise()
  .catch((e) => {
    console.log(e.message);
  });

Otherwise, neither resolve nor reject will be called, and the error was asynchronous, so the thread the Promise was created on has already ended, so the interpreter doesn't know that the thrown error should reject that Promise without you explicitly telling it to.

In contrast, errors thrown synchronously inside a Promise constructor will automatically result in the constructed Promise rejecting immediately.