Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I return explicitly after res.send in Express?

Tags:

express

I have the following code

const registerUser=async (req, res)=> {

    let incomingEmail=null,
    incomingPassword=null,
    firstName=null,
    lastName=null try {
        incomingEmail=req.body.email incomingPassword=req.body.password firstName=req.body.firstName lastName=req.body.lastName
    }

    catch(err) {}

    // verify name format
    const firstNameFormatIsValid=false  
    res.send(INVALID_FIRST_NAME) // adding this line produces error

    if (firstNameFormatIsValid===false) {
        res.send(INVALID_FIRST_NAME) // because it tries to send response back here again
    }
}

I am getting the following error Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client in my node code. I dont understand why res.send() is not returning implicitly.

Why does if (firstNameFormatIsValid===false) get executed when response has been returned?

like image 225
Vishal Avatar asked Oct 19 '25 23:10

Vishal


1 Answers

Should I return explicitly after res.send in Express?

Yes, if you have code after that res.send() in the function that normal Javascript execution flow would execute that you don't want to execute. If there is no other code after it in the function or the other code is protected by conditionals or the other code is just doing things like logging (that you want to execute) and not sending another response, then you don't need to add a return.

In a nutshell, you need to make sure in your code that no matter which code path things take in all your conditionals that your server sends one and only one response to each incoming request. Attempting to send more than once response to the same request generates a server warning and is a sign of a coding error.

Once res.send() has been called, the response stream is now done and closed. You can't send anything more on the response stream. That's how res.send() works. It flushes headers, then writes the body, then closes the stream (which closes the socket). There are ways to make multiple calls to send data using multiple calls to res.write(...) followed by res.end(), but that's only used when you have a reason to send a single response by using multiple writes (such as when streaming data from some other source that arrives in multiple chunks).

So, if you have this structure:

if (some condition) {
     res.send(...);
}

// some other code
res.send(...);

Then, you do need to return after the first response so that your function does not continue to execute the rest of the code in the function and then attempt to send another response.

if (some condition) {
     res.send(...);
     return;
}

// some other code
res.send(...);

On the other hand, if you had something like this:

if (some condition) {
     res.send(something);
} else {
     res.send(somethingDifferent);
}

then no explicit return statement is needed because your control flow already makes sure that only one response can be sent.


The code example you show here:

// verify name format
const firstNameFormatIsValid=false  
res.send(INVALID_FIRST_NAME) // adding this line produces error

if (firstNameFormatIsValid===false) {
    res.send(INVALID_FIRST_NAME) // because it tries to send response back here again
}

doesn't really make much sense because the first res.send() will always execute, therefore, there's no reason to have the second code block at all since you've already sent a response.

Why does if (firstNameFormatIsValid===false) get executed when response has been returned?

res.send() is JUST a function call. The Javascript interpreter just executes it like another other function call and then continues executing the rest of the function. While you may logically think that the function should now be done, the Javascript interpreter is just doing what it's being told to do, calling a function and when that returns, executing the rest of the function. If you want your function to stop executing more code in the function, you either throw (in cases of an error) or you return or you protect things with conditionals as in the third code block above.

like image 75
jfriend00 Avatar answered Oct 23 '25 04:10

jfriend00



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!