Multiple products are not added to cart, when one product has a error

Solved

Multiple products are not added to cart, when one product has a error

Michel2025
Shopify Partner
6 0 3

I have a javascript code that adds multiple products to my cart add once.
Based on this documentation: Add products to cart 

This normally works if non of the products has a issue like:

  • Not in stock.
  • Draft product.
  • Variant can not be found.

This are the basic response that i could get when doing this.
However it looks like all the other products are also not added to the cart when their is a issue.

Does anyone has a idee how to make these calls so that the products are added to cart except for the once that triggers those errors?

Accepted Solution (1)
goldi07
Navigator
364 38 69

This is an accepted solution.

You're welcome!
Just to clarify — in my example, the setTimeout wasn't for rate limiting — it was simply used to wait a bit before summarizing/logging how many products were added or failed (because the fetch calls are asynchronous).
But you're right to think about rate limits — Shopify does have limits (especially ~2 requests per second for storefront APIs like /cart/add.js).

If you are adding many products (like more than 2–3 at once), and you want to properly handle rate limits, you should actually queue the requests with a delay between them instead of blasting them all at once with forEach.

 

 

Here's a better version using a small delay between each request:

async function addProductsToCart(products) {
    let errors = [];
    let successfulAdds = 0;

    for (const product of products) {
        try {
            await addProductToCart(product);
            successfulAdds++;
            console.log(`Product ${product.id} added successfully.`);
        } catch (error) {
            errors.push({ product: product, error: error });
            console.log(`Error adding product ${product.id}: ${error.message}`);
        }

        // Wait 300ms between requests to be safe
        await new Promise(resolve => setTimeout(resolve, 300));
    }

    console.log(`${successfulAdds} products added to the cart.`);
    if (errors.length > 0) {
        console.log('Failed to add the following products:');
        errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
    }
}

Now each product will be added one by one, with a small 300ms pause between them to avoid hitting Shopify's rate limits.

 

In short:
. setTimeout in the first example = just waiting before logging the summary.

. Proper rate limiting = add a delay (await new Promise(resolve => setTimeout(resolve, 300))) after each product like in this new code.

. Shopify cart APIs aren't super strict, but it's still a good idea to throttle your requests when adding multiple items at once.

 

 

Thank you 😊

 

 

 

Was I helpful?

Buy me a coffee


APPS BY US :

Professional Customer Accounts APP


Want to modify or custom changes or bug fix on store . Or Need help with your store? Or -Want Complete Storefront
Email me -Goldi184507@gmail.com - Skype: live:.cid.819bad8ddb52736c -Whatsapp: +919317950519
Checkout Some Free Sections Here

View solution in original post

Replies 4 (4)

goldi07
Navigator
364 38 69

Hello @Michel2025 

 

To ensure that all products are added to the cart except the ones that trigger errors like "out of stock," "draft product," or "variant not found," you can modify your JavaScript code to handle each product individually. Instead of stopping the entire process when one product fails, you can process each product separately and catch the errors for each one. Here's a general approach you can follow:

 

Approach:
1. Loop through the products: For each product, you try to add it to the cart.

2. Error handling: If the product has an error (like being out of stock or a draft product), catch the error and skip adding that product to the cart.

3. Continue with other products: Continue processing the remaining products, even if one fails.

 

Example JavaScript Code:

function addProductsToCart(products) {
    let errors = []; // To store products that fail
    let successfulAdds = 0; // To track the successful additions

    // Loop through each product and try adding it to the cart
    products.forEach(product => {
        addProductToCart(product)
            .then(response => {
                successfulAdds++;
                console.log(`Product ${product.id} added successfully.`);
            })
            .catch(error => {
                errors.push({ product: product, error: error });
                console.log(`Error adding product ${product.id}: ${error.message}`);
            });
    });

    // After all products are processed, log the results
    setTimeout(() => {
        console.log(`${successfulAdds} products added to the cart.`);
        if (errors.length > 0) {
            console.log('Failed to add the following products:');
            errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
        }
    }, 1000); // Adjust time if needed based on your network latency or number of products
}

function addProductToCart(product) {
    return new Promise((resolve, reject) => {
        // Your logic to add the product to the cart
        // This example assumes you're using Shopify's AJAX API to add the product
        let formData = {
            items: [
                {
                    id: product.variantId,
                    quantity: product.quantity
                }
            ]
        };

        fetch('/cart/add.js', {
            method: 'POST',
            body: JSON.stringify(formData),
            headers: { 'Content-Type': 'application/json' }
        })
            .then(response => response.json())
            .then(data => {
                if (data.status && data.status === 404) {
                    reject(new Error('Variant not found'));
                } else if (data.status && data.status === 422) {
                    reject(new Error('Out of stock'));
                } else if (data.status && data.status === 500) {
                    reject(new Error('Product is a draft'));
                } else {
                    resolve(data);
                }
            })
            .catch(err => reject(err));
    });
}

 

Explanation:
. addProductsToCart(products): This function processes the list of products and attempts to add each one to the cart. If there's an error, it catches the error and logs it.

. addProductToCart(product): This function attempts to add a single product to the cart using Shopify's /cart/add.js API. It returns a promise that resolves if the product is added successfully or rejects with an error message if it fails (e.g., variant not found, out of stock, or product is a draft).

. The loop ensures that all products are processed, and even if one fails, the rest will still be added.

Error Handling:
. The catch block inside the forEach ensures that the script continues executing even if a product fails to add to the cart.

. reject(new Error('Variant not found')) and other similar errors are triggered when certain conditions (like the product being out of stock or not found) occur.

This approach should allow products to be added to the cart independently, even if some fail due to issues like those you mentioned.

 

Thank you 😊

Was I helpful?

Buy me a coffee


APPS BY US :

Professional Customer Accounts APP


Want to modify or custom changes or bug fix on store . Or Need help with your store? Or -Want Complete Storefront
Email me -Goldi184507@gmail.com - Skype: live:.cid.819bad8ddb52736c -Whatsapp: +919317950519
Checkout Some Free Sections Here
Michel2025
Shopify Partner
6 0 3

Thank you, i will look if your solution could help me.
The setTimeout is for the rate limit(to many request) i guess 

goldi07
Navigator
364 38 69

This is an accepted solution.

You're welcome!
Just to clarify — in my example, the setTimeout wasn't for rate limiting — it was simply used to wait a bit before summarizing/logging how many products were added or failed (because the fetch calls are asynchronous).
But you're right to think about rate limits — Shopify does have limits (especially ~2 requests per second for storefront APIs like /cart/add.js).

If you are adding many products (like more than 2–3 at once), and you want to properly handle rate limits, you should actually queue the requests with a delay between them instead of blasting them all at once with forEach.

 

 

Here's a better version using a small delay between each request:

async function addProductsToCart(products) {
    let errors = [];
    let successfulAdds = 0;

    for (const product of products) {
        try {
            await addProductToCart(product);
            successfulAdds++;
            console.log(`Product ${product.id} added successfully.`);
        } catch (error) {
            errors.push({ product: product, error: error });
            console.log(`Error adding product ${product.id}: ${error.message}`);
        }

        // Wait 300ms between requests to be safe
        await new Promise(resolve => setTimeout(resolve, 300));
    }

    console.log(`${successfulAdds} products added to the cart.`);
    if (errors.length > 0) {
        console.log('Failed to add the following products:');
        errors.forEach(err => console.log(`Product ${err.product.id} failed due to: ${err.error.message}`));
    }
}

Now each product will be added one by one, with a small 300ms pause between them to avoid hitting Shopify's rate limits.

 

In short:
. setTimeout in the first example = just waiting before logging the summary.

. Proper rate limiting = add a delay (await new Promise(resolve => setTimeout(resolve, 300))) after each product like in this new code.

. Shopify cart APIs aren't super strict, but it's still a good idea to throttle your requests when adding multiple items at once.

 

 

Thank you 😊

 

 

 

Was I helpful?

Buy me a coffee


APPS BY US :

Professional Customer Accounts APP


Want to modify or custom changes or bug fix on store . Or Need help with your store? Or -Want Complete Storefront
Email me -Goldi184507@gmail.com - Skype: live:.cid.819bad8ddb52736c -Whatsapp: +919317950519
Checkout Some Free Sections Here

Small_Task_Help
Shopify Partner
1054 45 102

Hi,

Hope this will help

- You need to add each product one by one, and if one fails, keep going.

JavaScript version example

const productsToAdd = [
  { id: 123456789, quantity: 1 },
  { id: 987654321, quantity: 2 },
  { id: 112233445, quantity: 1 }
];

async function addProductToCart(product) {
  try {
    const response = await fetch('/cart/add.js', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        items: [product]
      })
    });

    const data = await response.json();
    console.log(`Added product ${product.id} to cart.`);
  } catch (error) {
    console.warn(`Could not add product ${product.id}:`, error.message);
  }
}

async function addAllProducts(products) {
  for (const product of products) {
    await addProductToCart(product);
  }

  console.log('Done trying to add all products!');
}

addAllProducts(productsToAdd);

 

To Get Shopify Experts Help, Click Here or E-mail - hi@ecommercesmalltask.com
About Us - We are Shopify Expert India
At Google My Business - Ecommerce Small Task - Hire Shopify Developers Ahmedabad