Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit after res.send() in Express.js

I have a fairly simple Express.js app with a login component that I'd like to exit early if login fails. I'm seeing indications that the app isn't doing that and I haven't found a definitive answer that indicates whether calling res.send() halts any further processing. Here's my code as it stands now:

client.login( username, password, function( auth, client ) {
  if( !auth ) {
    res.send( 401 );
  }

  // DO OTHER STUFF IF AUTH IS SUCCESSFUL
}

If I read the source code correctly, it should end the request (aborting further processing), but I'm new to node, so I'm not quite ready to trust what I think I'm reading. To boil it down, I guess I'm mostly looking for a definitive answer from a more trustworthy source that my own interpretation of unfamiliar source code. If send() doesn't abort processing, what's the right way to do that?

like image 671
Rob Wilkerson Avatar asked Feb 05 '13 14:02

Rob Wilkerson


People also ask

What happens after Res send?

res. send() or res. json() should end all writing to the response stream and send the response. However, you absolutely can call next() if you want to do further processing after the response is sent, just make sure you don't write to the response stream after you call res.

Does Res send end the function?

send doesn't return the function, but does close the connection / end the request.

What does Res send () do?

The res. send function sets the content type to text/Html which means that the client will now treat it as text. It then returns the response to the client.

What does res sendFile return?

res.sendFile(path [, options] [, fn]) Parameter: The path parameter describes the path and the options parameter contains various properties like maxAge, root, etc and fn is the callback function. Returns: It returns an Object.


3 Answers

Of course express can not magically make your javascript function stop executing from somewhere else.

I don't like the next([error]) solution because I think errors should be only used for circumstances you usually don't expect (like an unreachable database or something). In this case, a simple wrong password would cause an error. It is a common convention to not use exceptions/errors for ordinary control flow.

I therefore recommend to place a return statement after the res.send call to make your function stop executing further.

client.login( username, password, function( auth, client ) {   if( !auth ) {     res.send( 401 );     return;   }    // DO OTHER STUFF REALLY ONLY IF AUTH IS SUCCESSFUL } 
like image 102
Steve Beer Avatar answered Sep 21 '22 14:09

Steve Beer


If you are using express as your framework, you should call next() instead.

Each handler in express receives 3 parameters (unlinke 2 for basic http) which are req, res and next

next is a function that when called with no arguments will trigger the next handler in the middleware chain.

If next is called with an arguments, this argument will be interpreter as an error, regardless of the type of that argument.

Its signature is next([error]). When next is called with an error, then instead of calling the next handler in the middleware chain, it calls the error handler. You should handle the 401 response code in that error handler. See this for more info on error handling in Express

EDIT: As @Baptiste Costa commented, simply calling next() will not cease the current execution but it will call on the next middleware. It is good practice to use return next() instead to prevent Node from throwing errors further on (such as the can't set headers after they are sent - error). This includes the above suggestion of error throwing which is common:

return next(new Error([error])); 
like image 22
Floby Avatar answered Sep 18 '22 14:09

Floby


For your specific case you can just add the 'else' statement:

client.login( username, password, function( auth, client ) {
    if( !auth ) {
        res.send( 401 );
    }else {
       // DO OTHER STUFF IF AUTH IS SUCCESSFUL
    }
}

Or, in general, you can use 'return':

return res.send( 401 );
like image 32
RoccoDen91 Avatar answered Sep 18 '22 14:09

RoccoDen91