After sending response, how to end the current request processing in Node/Express?

13,820

According to the express documentation on http://expressjs.com/guide/using-middleware.html

If the current middleware does not end the request-response cycle,
it must call next() to pass control to the next middleware,
otherwise the request will be left hanging.

so if a middleware needs to end the request-response early, simply do not call next() but make sure that the middleware really ends the request-response by calling res.end, res.send, res.render or any method that implicitely calls res.end

app.use(function (req, res, next) {
  if (/* stop here */) {
    res.end();
  } else {
    next();
  }
});

Here is an example server showing that it works

var express = require('express');
var app = express();

var count = 0;
app.use(function(req, res, next) { 
  console.log('f1'); 
  next();
 })
app.use(function(req, res, next) {
  console.log('f2');
  if (count > 1) {
    res.send('Bye');
  } else {
    next();
  }
})
app.use(function(req, res, next) {
  console.log('f3');
  count++;
  next();
})

app.get('/', function (req, res) {
  res.send('Hello World: ' + count);
});

var server = app.listen(3000);

you will see the after 3 requests, the server shows "Bye" and f3 is not reached

Share:
13,820

Related videos on Youtube

Sunny
Author by

Sunny

Web designer .

Updated on July 09, 2022

Comments

  • Sunny
    Sunny almost 2 years

    There are a few posts on this question but none that answers the issue directly, head-on. Let me clarify that I understand (or so I think) the use of next(), next('route'), return next(), return and their impact on control flow. My entire middleware for the app consists of a series of app.use, as in:

     app.use(f1);
     app.use(f2);
     app.use(f3);
     app.use(f4);
     ...
    

    In each of these middlewares, I have possibility of sending the response and be done without any need for further processing. My problem is that I am unable to stop the processing from going to the next middleware.

    I have a clumsy work around. I just set a res.locals.completed flag after sending a response. In all the middlewares, at the very start, I check this flag and skip processing in the middleware if the flag is set. In the very first middleware, this flag is unset.

    Surely, there must be a better solution, what is it? I would think that Express implicitly would do this checking and skip the middlewares through some express-specific method?

    • maxdec
      maxdec over 8 years
      Can you show what's in f1, f2, etc.? If you use res.send(...) and do not call next(), you should terminate the request-response cycle while not going into the next middleware.
  • Jerome WAGNER
    Jerome WAGNER over 8 years
    I am not sure I understand. calling next() means that you want the next middleware to be called. You want the next middleware to be called but not executed ??
  • Sunny
    Sunny over 8 years
    If a response is sent in middleware f1, I do not want other middlewares to be called for this request. I am referring to other middlewares in the app.use list. Now, I am setting a flag (in req or res object) on sending a response and when the other middlewares are called (because I cannot figure out how to stop that from happening after a send()), they first check the flag and if the flag is set, they simply call return thereby skipping execution and moving to the next middleware... It works but I want a better way...
  • Jerome WAGNER
    Jerome WAGNER over 8 years
    see my example server in the answer. Not calling next() and calling res.send() correctly stops the middleware flow
  • Sunny
    Sunny over 8 years
    Your code confirms what I thought should happen. I think there must be some other error in my code. I will check that. Accepting your answer. Helped clarify my doubts. Thanks. I think that your answer will be of help to others too, for sure.
  • Sunny
    Sunny over 8 years
    Can you take a look at this question?stackoverflow.com/questions/33748618/…
  • Simo Erkinheimo
    Simo Erkinheimo almost 7 years
    Something like these examples should be edited into the Express documentation. At the very least, the documentation should define what constitutes "end[ing] the request-response cycle" as you have clearly done here.