Trap mistakes while utilizing async/await

Within my Express application, I have a register function for creating new users. This function involves creating the user in Auth0, sending an email, and responding to the client.

I am looking to handle errors from Auth0 or Postmark individually and send specific error messages back to the client while logging them. My initial approach was to use async/await with a catch block instead of chaining multiple .then() and .catch() blocks. However, despite sending the error to the client, it does not halt the code execution. As a result, the email part attempts to execute while the user object is undefined, leading to the error "Cannot set headers after they are sent to the client."

How can I resolve this issue while maintaining the async/await functionality and separate error handling for each action?

Register function

export const register = asyncHandler(async (req, res, next) => {
    // Create user in Auth0
    const user = await auth0ManagementClient.createUser({
        email: req.body.email,
        password: generateToken(12),
        verify_email: false,
        connection: 'auth0-database-connection'
    }).catch((error) => {
        const auth0_error = {
            title: error.name,
            description: error.message,
            status_code: error.statusCode
        }

        console.log(auth0_error);

        if(error.statusCode >= 400 && error.statusCode < 500) {
            return next(new ErrorResponse('Unable to create user', `We were unable to complete your registration. ${error.message}`, error.statusCode, 'user_creation_failed'));
        } else {
            return next(new ErrorResponse('Internal server error', `We have issues on our side. Please try again`, 500, 'internal_server_error'));
        }
    });

    // Send welcome mail
    await sendWelcomeEmail(user.email)
        .catch((error) => {
            const postmark_error = {
                description: error.Message,
                status_code: error.ErrorCode
            }

            console.log(postmark_error);

            if(error.statusCode >= 400 && error.statusCode < 500) {
                return next(new ErrorResponse('Unable to send welcome email', `We were unable to send a welcome email to you`, error.statusCode, 'welcome_email_failed'));
            } else {
                return next(new ErrorResponse('Internal server error', `We have issues on our side. Please try again`, 500, 'internal_server_error'));
            }
        });


    res.status(201).json({
        message: 'User succesfully registered. Check your mailbox to verify your account and continue the onboarding.',
        data: {
            user
        }
    });
});

asyncHandler.js

const asyncHandler = fn => ( req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);

export default asyncHandler;

Answer №1

To handle errors gracefully, I recommend using try/catch blocks while ensuring the user variable is declared outside of the try scope.

async function processRequest(req, res, next) {
  let user;

  try {
    user = await userData.createUser(...);
  } catch (error) {
    return next(new CustomError(...));
  }

  try {
    await sendNotification(user.email);
  } catch (error) {
    return next(new CustomError(...));
  }

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

Answer №2

Return will specifically end the current function. In this case, the .catch() callback is the function that gets ended by the return.

In your scenario, if you prefer sticking with Promise.then().catch(), you can verify the user value as the catch() callback will return its value.

An alternative approach would be to utilize try/catch blocks to halt the entire controller using the return statement.

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

Is there a way to stop text from wrapping between words and punctuation marks using CSS or jQuery?

There is a paragraph containing some text. One issue I am facing is that punctuation at the end of a word may get wrapped to the next line, as shown here: This is the sentence, This is a new line Is there a way to fix this using CSS or jQuery? ...

Some design elements are present in the interface. The functionality of the data tables is working properly, however, upon reloading the page, the table header shrinks. Interestingly

[![enter image description here][1]][1] This is the JavaScript code along with my footer and header references. The issue I am facing is with the design - initially, it shows a buggy design but when I click on the header, it displays the correct design. & ...

What is the best way to parse a JSON file in Angular?

Can you please explain how to read a JSON file? I have been able to successfully read a JSON file using a controller, but when I try to read it from a factory, the content is null. Why is this happening? http://plnkr.co/edit/THdlp00GuSk1NS6rqe5k?p=preview ...

Error encountered while testing karma: subscription function is not recognized

I encountered an issue with my karma unit test failing with the following error message. "this.gridApi.getScaleWidth().subscribe is not a function" GridApi.ts export class GridApi { private scaleWidthSubject = new BehaviorSubject<{value: number}& ...

The jQuery .post method is not returning any data when using the done and fail functions

I've encountered an issue while attempting to execute a jQuery AJAX request and retrieve the data in the .done and .fail methods. Below is the snippet of code that triggers the AJAX request: async function doSomething(){ const addressValid = awai ...

JavaScript function unable to access static file for image

I need assistance with dynamically displaying an image (a checkmark or "X") based on a variable. When I insert the image using a script directly in the HTML file, it functions correctly. However, when attempting to set the image from within the createEasyD ...

Show the selected checkbox options upon clicking the submit button

Having trouble setting up a filter? I need to create a feature where checked values from checkboxes are displayed in a specific div after submitting. The display should include a 'Clear All' button and individual 'X' buttons to remove e ...

Incorporating JavaScript into a pre-existing HTML and CSS user interface

After successfully coding a chat app UI for my project site using CSS and HTML, I am now facing the challenge of adding functionality to my existing code. The issue is setting up the client server and integrating chatting functions into my current UI. Mo ...

When attempting to view the PDF file, it appears completely void

After spending countless hours on this task, I'm still not making any progress. My goal is to download a PDF file from my server while currently running the operation on localhost. However, whenever I open the downloaded PDF, all I see is a blank whit ...

Utilizing $templateCache with ui-router and minifying in AngularJS 1.x

Posting this as a question-answer post. How can one effectively utilize the $templateCache in the templateProvider of a route within ui-router when attempting to refactor the code? Injection is ineffective, and Angular cannot inject by reference. For ins ...

Implementing Do Not Track in an express application

I am trying to implement a feature named "consent" in my Nodejs express app that utilizes the Do Not Track (DNT) functionality from browsers. This function is supposed to integrate Google analytics on rendered pages only when DNT is not active or its state ...

Having troubles with delayed state changes due to setState being used within useEffect

I have been working on a slider effect using React Hooks and Redux, and here is the code I am using: const Barchart = ({chartData}) => { let newArray = [] let len = chartData.length const [XArray,setXArray]=useState([chartData]) const [ ...

Disable Jquery toolstrip while the menu is open

Currently, I am utilizing the jQuery toolstrip plugin in my project. I have a requirement to disable it whenever the sidebar menu is opened. Below are the HTML codes for my menu with li tags: <div class="sidebar-wrapper" id="sidebar-wrapper"> <ul ...

Dynamic text input and selection menu with AJAX (PHP and JavaScript)

As a student who is new to Javascript and PHP, I am trying to create a login page for my website that can verify user input in the database using AJAX. For example, when a user enters their username and password, the system should automatically check if t ...

Customizing table headers in Yajra Laravel Datatables

I am encountering an issue with category sorting on my list of products. When I click on category sorting, it only shows the same category and product name repeatedly. All other sorting functions are working correctly, except for category sorting. I have ...

Implementing pagination and filtering in a single MERN controller

Is it possible to implement pagination and filtering in the same controller? Filter service:- const filterPosts = async (filterData, token) => { const config = { headers: { Authorization: `Bearer ${token}`, }, data: { ...

Exploring the connections between Ajax, asp.net mvc3 routing, and navigating relative URLs

My ASP.NET MVC3 application is live at a URL like this: http://servername.com/Applications/ApplicationName/ In my code, I am making jQuery AJAX requests in this manner: $.get(('a/b/c'), function (data) {}, "json"); When running the applicati ...

Required attributes not found for data type in TypeScript

When the following code snippet is executed: @Mutation remove_bought_products(productsToBeRemoved: Array<I.Product>) { const tmpProductsInVendingMachine: Array<I.Product> = Object.values(this.productsInVendingMachine); const reducedPro ...

Insert fresh user information into the div

Learning JavaScript is a challenge I'm tackling. I have a question that may seem trivial, but any assistance would be greatly appreciated. I currently have this code: Javascript <script type="text/javascript"> function fn(){ var Name = ...

What is the best way to create a fixed footer in Next.js using React?

I'm looking to create a fixed footer that will stay at the bottom of the page if there isn't enough content to fill it. I've been researching ways to achieve this using CSS, but many of the methods don't easily translate to React/Next.j ...