How to manage rejections in async/await within the Array#map method

In my Node 8.1.2 project, I encountered a scenario where one file is calling another file's function within a map structure. While in a real example, I would normally use Promise.all on the map, that specific implementation is not the focus of this question. Here is the existing structure:

A.js:

const { b } = require('./B')

function expressStuff (req, res, next) {
  things.map(thing => {
    return b(thing)
  }))

  return res.status(200).json(...)
}

B.js:

// Thing -> Promise<Object>
function b (thing) {
  return ThingModel.update(...) // Even though this returns a Promise, it fails and throws an error
}

module.exports = { b }

Inside the b function, there is an attempt to fetch async data from a database, which results in an Uncaught Promise Rejection.

How can this issue be resolved?

I have experimented with various solutions:

A1.js:

const { b } = require('./B')

function expressStuff (req, res, next) {
  things.map(thing => {
    try {
      return b(thing)
    } catch (err) {
      return next(err)
    }
  }))

  return res.status(200).json(...)
}

Unfortunately, this approach still does not handle the error correctly.

A2.js:

const { b } = require('./B')

function expressStuff (req, res, next) {

  try {
    things.map(thing => {
      return b(thing)
    }))
  } catch (err) {
    return next(err)
  }

  return res.status(200).json(...)
}

This method also proves to be ineffective in handling the error properly. Despite attempts including using Promise.all and double try-catch blocks, the error remains unhandled.

The closest solution found so far was to manage the error within the function itself, but this resulted in code execution not waiting for the error to be thrown, leading to race conditions and errors related to setting headers after they are already sent.

The main objective is to allow the function b to throw an error and catch it in the expressStuff function to rethrow a custom UnprocessableEntityError through next. It seems like the error originating from file B is not propagating up to the map where it is invoked.

How can this desired behavior be achieved?

UPDATE:

The only way I managed to handle this rejection was by implementing a try-catch within B.js. However, any attempts to rethrow or return the error were unsuccessful as the error seemed to get swallowed. Interestingly, logging the error using console.log did work.

FURTHER DETAILS:

Following the advice provided in the accepted answer, I refactored my actual code and successfully resolved the issue:

function expressStuff (res, req, next) {
  try {
    await Promise.all(things.map(async thing => {
      if (ifSomething()) {
        await b(thing)
      }
    }))
  } catch (err) {
    return next(new MyCustomError('My Custom Error Message'))
  }

  return res.status(200).json(...)
}

Answer №1

Dealing with rejections using try/catch is effective only within async functions when the promise is awaited - something you have not tried yet.

You have two options:

async function handleStuff (req, res, next) {
  var results;
  try {
    results = await Promise.all(things.map(b)); // throws an error if any promises are rejected
  } catch (err) {
    return next(err) // deal with the error
  }
  return res.status(200).json(...)
}

or (similar to Wait until all ES6 promises complete, even rejected promises)

function handleStuff (req, res, next) {
  const resultPromises = things.map(async (thing) => {
    try {
      return await b(thing); // throws an error if the promise for this particular thing is rejected
    } catch (err) {
      return defaultValue; // handle the error without calling `next`
    }
  });
  …
  return res.status(200).json(...)
}

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

The combination of Express 3.0, Everyauth, and HTTPS creates a powerful

Currently, I am working with nodejs and using express 3 along with everyauth for google oauth. The setup appears as follows: everyauth.google /* snip */ .callbackPath('/loggedin'); var app = express(); app.configure(function(){ /* snip */ ...

Preventing input in one textbox if another textbox has a filled value in HTML

Apologies for asking this question, but is there a way to disable one text box if another text box has a value? I've attempted using the following code, but it doesn't seem to work. Sorry for the inexperienced inquiry T_T function disableTextbox ...

Adding a JavaScript widget to a WordPress page

Good morning! I need to place an affiliate external widget on a WordPress page. The code I have loads external content within the page. <script type="text/javascript" src="http://www.convert.co.uk/widget/mobiles.js"></script> The placement o ...

The output of the Node.js crypto.pbkdf2 function may not match the result obtained from CryptoJS.PBKDF

Currently, I am utilizing PBKDF2 on both the frontend with CryptoJS and the backend with Node.js. Despite using the identical salt, algorithm, number of iterations, and password, the derived keys are turning out to be different. Below is the code snippet ...

Organize routes into distinct modules in Angular 6

Currently grappling with routing in my Angular 6 application. Wondering if the structure I have in mind is feasible. Here's what it looks like: The App module contains the main routing with a parent route defining the layout: const routes: Routes = ...

What steps can be taken to address the UnhandledPromiseRejectionWarning?

Greetings and good day to you! I am facing an issue with user authentication. When I try to log in a registered user, it gets stuck loading forever and shows an error message: "UnhandledPromiseRejectionWarning: ReferenceError: Invalid left-hand side ...

Guide on converting HTML datetime picker datetime-local to moment format

I am looking to convert an input type : <input type="datetime-local" name="sdTime" id="stTimeID" onChange={this.stDateTime} /> into a specific date format: const dateFormat = 'MM/DD/YYYY hh:mm:ss a'; To achieve this, I need to transfer ...

Tips for handling an incorrect date entry when a field loses focus in AngularJS

If I have an <input> field with the type='date' attribute in its untouched state, it displays mm/dd/yyyy as the date format. I am looking to see if there is a way to utilize AngularJS ng-blur directive to reset the field to this original fo ...

The jQuery .post function is successfully executing, but it is strangely triggering the .fail method without

My data is successfully being posted, but I'm struggling to get my .post response handler code to work efficiently. The results seem inconsistent across different browsers and tools that I have tried. Here's the code snippet for the post: $.post ...

Is it possible to retain various delimiters after dividing a String?

In the code below, the someString gets split into an array using specified delimiters in separators var separators = ['\\.', '\\(', '\\)', ':', '\\?', '!&apos ...

Is a webpage's sluggishness in Internet Explorer due to its lengthy page structure causing issues while loading quickly on other browsers?

My application has a page that is particularly long, around 8Mb of source HTML mainly comprised of tables. I am aware that this indicates poor architecture, but unfortunately, I am unable to make immediate changes due to certain constraints. In most brows ...

Experiencing Issues Connecting to AWS RDS MySQL Database Through Express JS

I have been attempting to establish a connection with my Amazon RDS cloud database using the Express framework. The connection setup in my server.js file is as follows: const express = require('express'); var bodyParser = require('body-pars ...

Configuring the maxAge setting in Node.js Express

What happens if I specify maxAge in the sendFile() method as shown below: res.sendFile('public/index.html', {maxAge: 100000}) Will this cache the file 'public/index.html' in the server's memory for 100 seconds? Or is it simply a ...

Pass the axios response between two separate JavaScript files

I am trying to make an axios GET request with the following code snippet: getData.js const int_postData = ({ 'grant_type': 'client_credentials' }); axios.post(token_url, int_postData, { headers: { "Authorization&qu ...

Using asynchronous data in Angular 2 animations

Currently, I have developed a component that fetches a dataset of skills from my database. Each skill in the dataset contains a title and a percentage value. My objective is to set the initial width value of each div to 0% and then dynamically adjust it t ...

Passport.js encountered an issue when attempting to serialize the user for the session

I'm having trouble with the Passport.js module and Express.js. My code is set up for a hardcoded login for testing purposes. However, I keep getting the error message: I've searched online for solutions on Stack Overflow, but I can't seem ...

What is the process for populating a checkbox with data from a configuration file using JavaScript?

I have a requirement where I need to populate a list of checkboxes with data from a configuration file. To elaborate, if my checkboxes are meant to select sports, within my JSON configuration file I have an array like this: sports: ["Tennis", "Rugby", "S ...

Angular 2 Issue: Error Message "Cannot bind to 'ngModel'" arises after FormsModule is added to app.module

I've been struggling with the data binding aspect of this tutorial for over a day now. Here's the link to the tutorial: https://angular.io/docs/ts/latest/tutorial/toh-pt1.html The error I keep encountering is: Unhandled Promise rejection: Tem ...

Node.js TCP server sequentially processes incoming packets

In my Node.js application, I am utilizing a TCP server to receive and handle packets. The server should expect to receive two specific types of packets: "create" which is responsible for creating an object in a database. This process involves ch ...

Is there a way to push the modifications I've made in node_modules back to git?

At times, maintaining a fork of a node package for your module can be more convenient. I am looking to make edits to a module that is located in node_modules, which I installed using npm install githubaccount/myrepo.git. Currently, any changes I make to a ...