Jay's blog

Express's "finish" Event

Let's say you want to write some middleware for Express that does something after the request is complete. The standard advice on the web is to add an event listener to the response object listening for the "finish" event.

app.use(function(req, res, next) {
  // DON'T USE THIS!!!
  res.on('finish', function() {
    console.log('Request finished');
  });
  next();
});

I learned the hard way that the "finish" event doesn't always get fired. There are lots of ways you can screw this up as a programmer. "finish" may not fire if:

But even if you're the best, most diligent programmer on Earth, if the client closes the connection before the request has been completed, that's enough to cause the "finish" event to never fire for that request.

Maybe that's the behavior you want. Maybe you only want your event listener to fire on successful requests. If so, carry on. But if you're like me and you want your event listener to fire after every request, you should listen for a different event. I fixed my issue by listening for the "close" event, which is always fired.

app.use(function(req, res, next) {
  res.on('close', function() {
    console.log('Request finished');
  });
  next();
});