Is it a mistake to gather errors together and send them to the promise resolve in JavaScript?

When processing a list in a loop that runs asynchronously and returns a promise, exiting processing on exception is not desired. Instead, the errors are aggregated and passed to the resolve callback in an outer finally block. I am curious if this approach is considered an anti-pattern and would appreciate guidance on the correct way to handle this situation. Thank you.

Here is an example:

async doSomething(list) {
let errorCount = 0
let errors = []
return new Promise(async (resolve, reject) => {
  try {
    list.forEach(async (item) => {
      try {
        actionThatThrows(item)
      } catch (e) {
        errorCount++
        errors[errorCount] = e
      }
    })
  } catch (e) {
    errorCount++
    errors[errorCount] = e
  } finally {
    if (errorCount > 0) {
      resolve(errors)
    } else {
      resolve()
    }
  }
})

}

Answer №1

Avoid these common antipatterns in your code:

  • Do not pass an async function to a Promise constructor
  • Avoid using the Promise constructor unnecessarily if you already have promises available
  • forEach does not support async functions

If I encounter an exception, my goal is to handle them collectively rather than abruptly ending the process

Consider exploring How to manage multiple ES6 promises, including those that fail for further guidance.

If you prefer a sequential approach without utilizing the aforementioned methods, you can accomplish it like this:

async function doSomething(list) {
    const errors = [];
    for (let item of list) {
        try {
            await actionThatThrows(item);
        } catch (e) {
            errors.push(e);
        }
    }
    if (errors.length)
        return errors;
    else
        return …;
}

Answer №2

The mistakes stem from the asynchronous computation being carried out, giving it an appearance of authenticity on a broader scale.

If we assume that actionThatThrows is expected to return a promise (though this isn't explicitly stated in your query or code), the function could potentially be rephrased as follows:

function performTask(array) {
    let errors = []
    return Promise.all(array.map(
        item => actionThatThrows(item).catch(e => {
            errors.push(e);
        })
    )).then(()=>{
        return errors.length ? errors : undefined;
    });
}

Answer №3

1) The async keyword in doSomething is redundant as it is not invoking an await, so it can be removed. 2) Similarly, the async keyword in list.forEach does not invoke an await, so it should also be removed. 3) The first catch block will handle all errors, making the second catch and finally blocks unnecessary.

The code can be simplified as follows:

doSomething(list) {
    let errorCount = 0,
        errors = [];
    for (let item of list) {
        try {
            actionThatThrows(item); // Assuming this does not return a promise
        } catch (e) {
            errorCount += 1;
            errors[errorCount] = e;
        }
    }
    if (errorCount > 0) {
        return errors; // Return Promise.reject(errors);
    } else {
        //return Promise.resolve();
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Middleware functions in Mongoose for pre and post actions are not being triggered when attempting to save

After carefully reviewing the documentation, I am still unable to pinpoint the issue. The pre & post middleware functions do not appear to be functioning as expected. I have made sure to update both my node version and all modules. // schema.js const sch ...

Ways to guarantee the protection of APIs that are accessible to both front-end applications and other servers

In the process of creating a website, I am faced with the challenge of enabling the front-end page to communicate with the server using AJAX for data retrieval and posting. The same APIs offered by the server are also utilized by private apps within the ...

Issue with verifying file existence utilizing $.ajax()

I'm currently facing a challenge checking for the existence of a file using $.ajax(). I am cycling through a JSON file with $.each and trying to determine if a specific staff member has an image. If not, I want to default to using the no_photo.jpg ima ...

I'm encountering an unfamiliar error within my Discord.js bot, and I'm unsure of both its cause and the appropriate solution. Additionally, I'm unsure which specific file

I'm facing a recurring issue with my bot terminal. It's been causing me trouble for the past four days, functioning intermittently without any pattern. I'm struggling to track down the specific file where this error is originating from. Any ...

The file could not be loaded as a result of Multipart: The boundary was not detected

Having trouble uploading images from my desktop due to a multipart boundary error. How can I set a proper boundary for image uploading? Any advice would be greatly appreciated as this is my first time attempting image uploads. Implementing an HTML event l ...

Efficiently converting HTML object data into plain text using RegExr in ReactJS and JavaScript

Is there a way to convert an object in JavaScript/ReactJS into a string? For instance, consider the following object: { article: '<p class="md-block-unstyled">First text...</p><p>Second text></p>' } I am looking to ...

How can I detect Mongoose events through syntax?

Is there a way to detect the open event in Mongoose based on their documentation located here? According to the documentation, once connected, the open event is fired on the Connection instance. If you're using mongoose.connect, the Connection is m ...

Having trouble importing Bootstrap into Next.js? It seems like the issue may be related to the

I am currently facing an issue with importing bootstrap 5.3.2 (not react-bootstrap) into my NextJS 14.1.0 project that utilizes the new App Router. My goal is to strategically utilize individual Bootstrap components (not through data-attrs). I managed to ...

Determining the navigation changes within a React browser

Hi there, I'm using browserHistory.goForward() and browserHistory.goBack() to navigate forward and backward in my app with arrow buttons. However, I need a way to determine if the route has actually changed after executing browserHistory.goForward/goB ...

Is Jquery getting imported correctly, but AJAX is failing to work?

I am currently working on a Chrome extension that automatically logs in to the wifi network. I have implemented AJAX for the post request, but when I inspect the network activity of the popup, I do not see any POST requests being sent. Instead, it only sho ...

Looking for a way to efficiently add multiple value inputs to a JSON object using jQuery or JavaScript?

Here is the HTML input tag code I am working with: <form id="info"> <input id="A" name="A" type="hidden" nodetye="parent" value="A"> <input id="A1" name="A1" type="text" nodetype="child" value="a1val"> <input id="A2" name ...

Creating unique sizes for each quad in Three.js using InstancedBufferGeometry and ShaderMaterial

I'm working on creating a visually dynamic scene filled with points of varying widths and heights. The challenge I'm facing is figuring out how to manipulate the vertices in the vertex shader to achieve customized sizes for each point. Here' ...

JavaScript and HTML with Node.js

Exploring the world of HTML, running smoothly with a static IP address 192.168.56.152 using apache on the host computer. <!DOCTYPE html> <html > <head> <title>OnlinePage</title> <meta charset="utf-8"& ...

tips on customizing buttons within form groups

I have set up two separate form-groups: My goal is to click on each button within each group and toggle its style from grey to green, and vice versa. However, when I click on a button, all buttons within the group turn grey except for the one that was cli ...

Is there a way to lead to a password-protected page without making it accessible through the URL?

I'm currently honing my skills in web development and embarking on a project to create an interactive puzzle website. The premise is simple - the homepage will feature just an answer input field where users can enter the correct solution to progress t ...

The error I encountered with the Typescript React <Select> onChange handler type was quite

Having an issue while trying to attach an onChange event handler to a Select component from material-ui: <Select labelId="demo-simple-select-label" id="demo-simple-select" value={values.country} onChange={handleCountryChange} ...

Conceal and reveal elements using v-if

Check out my fiddle: DEMO creating a new Vue instance: { el: '#app', data: { modules: ['abc', 'def'] } } I am looking for a way to hide or show elements using v-if based on the values in an array called modules[]. ...

What is the best way to create a reusable component for a dialog box or modal window?

I have been working on developing a reusable dialog component with a yes or no button at the bottom. The main idea behind this is to create a user confirmation dialog that prompts the user to confirm their entered information before proceeding. import Re ...

"Troubleshooting: Difficulty with hover function in jqgrid not functioning on colored rows

My JQGrid setup includes the following: <table id="grid"></table> var data = [[48803, "DSK1", "", "02200220", "OPEN"], [48769, "APPR", "", "77733337", "ENTERED"]]; $("#grid").jqGrid({ datatype: "local", height: 250, colNa ...

What is the method for retrieving the active element with Waypoint?

Currently, I am implementing Waypoint (version 7.3.2) in my React project using React version 16. My goal is to create a scrollable list of items where each item fades out as it reaches the top of the container div. My main inquiry is how can I obtain a re ...