Open In App

Why Promise.all doesn’t reject when a non-promise throws an error ?

Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will talk about why Promise.all() method does not get rejected when one of the non-input promises throws an error, and in which cases the Promise.all() does get rejected.

Promise.all() is a method that returns a promise. It takes an array of promises as its argument and returns a single promise, which gets rejected even if one of the promises (passed as an argument) gets rejected. 

Example 1:

Javascript




<script>
    const promise1 = Promise.resolve("Hello world");
    const promise2 = Promise.resolve("GFG");
    const promise3 = Promise.resolve("success")
  
    // when all the promises are resolved, 
    // Promise.all() gets resolved as well
    Promise.all([promise1, promise2, promise3]).then(res => {
        console.log(res);
    });
</script>


Output:

["Hello world", "GFG", "success"]

Example 2:

Javascript




<script>
    const promise1 = Promise.resolve("Hello world");
    const promise2 = Promise.resolve("GFG");
    const promise3 = Promise.reject("promise rejected")
  
    // If any one (or more) of the promises 
    // get rejected, the Promise.all()
    // gets rejected too with the rejection 
    // message of the first 
    // rejected promise it encountered
    Promise.all([promise1, promise2, promise3]).catch(error => {
  
        // output - "Promise rejected"
        console.log("Promise rejected"); 
    });
</script>


Output:

Promise rejected

Now, let’s try to reproduce a case when Promise.all() does not get rejected when one of the array elements (passed as an argument to Promise.all()) throws an error.

Javascript




<script>
    const promise1 = Promise.resolve("Hello world");
    const promise2 = () => {
        throw new Error("error!");
    };
    const promise3 = Promise.resolve("GFG");
  
    Promise.all([promise1, promise2(), promise3])
        .then(res => {
            console.log(res);
        })
        .catch(error => console.log("Promise rejected!"));
</script>


Output:

Code output

As we can see in the output above, even though the promise2 function throws an error, the Promise.all() method does not get rejected, and the browser throws an unhandled error. At first glance, this might seem an unusual case, but on careful analysis, one can observe the reason why Promise.all() does not get rejected here because the promise2 function does not actually return a promise, and it throws an error even before Promise.all() is called (if you see the Promise.all() argument, promise2 is called inside the argument itself, thus causing it to throw an error before Promise.all() itself is called). 

Now, to solve this problem, let’s look at some of the below approaches – 

Approach 1: Converting non-promise array elements into promise objects

In this approach, we will make sure that the array, is passed to the Promise.all() method, has all elements as promise objects. This way, we can be sure that none of the array elements returns a response before the Promise.all() is executed.

Example:

Javascript




<script>
    const promise1 = Promise.resolve("Hello world");
    const promise2 = async () => {
        throw new Error("error!");
    };
    const promise3 = Promise.resolve("GFG");
  
    Promise.all([promise1, promise2(), promise3])
        .then(res => {
            console.log(res);
        })
        .catch(error => console.log("Promise rejected!"));
</script>


In the code above, we used async in the promise2 function as we know that all async functions return a promise as a response.

Output:

Code output

Approach 2: Creating a then() method inside the non-promise array element

In this approach, we will create a then() method inside the non-promise array element and throw the error inside the method. This is to ensure that the error is not thrown until the then() method is called, and then when the error is thrown, the Promise.all() gets rejected. 

Example:

Javascript




<script>
    const promise1 = Promise.resolve("Hello world");
    const promise2 = {
  
        // Create a then() method which is 
        // called in Promise.all()
        then() {
            throw new Error("error!");
        }
    };
    const promise3 = Promise.resolve("GFG");
  
    Promise.all([promise1, promise2, promise3])
        .then(res => {
            console.log(res);
        })
        .catch(error => console.log("Promise rejected!"));
</script>


Output:

 



Last Updated : 01 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads