Express Response End Event Middleware

raw JSON →
0.0.8 verified Thu Apr 23 auth: no javascript abandoned

The `express-end` package provides a specific Express middleware designed to augment the default event handling on the `res` (response) object. Its primary function is to emit an `end` event whenever `res.end()` is called, crucially, even if the client connection has closed prematurely. This addresses a common limitation where the standard `finish` event on the `res` object might not reliably fire under such circumstances, preventing middleware from consistently determining when server-side processing for a request has fully concluded. This capability is useful for tasks like consistent post-request logging, resource cleanup, or metric collection. The package is currently at version `0.0.8` and has not been updated since 2016, indicating it is an abandoned project. Its core differentiator is providing a consistent signal for server-side request completion, regardless of client connection status, a problem that might be solved differently or directly in modern Express versions.

error TypeError: app.use is not a function
cause Attempting to use `express-end` in an environment where `app` is not a valid Express application instance, or if `express` itself is not properly installed or imported.
fix
Ensure express is installed (npm install express) and app = express(); is correctly initialized before app.use(endMw);.
error The 'end' event does not fire consistently, or conflicts with other response handling.
cause This is a consequence of the monkey-patching approach of `express-end` potentially conflicting with other middleware that also modifies `res.end()`, or due to changes in Express's internal `res` object structure in newer versions, leading to silent failures.
fix
Thoroughly test express-end in isolation and with all other middleware. If conflicts arise, consider replacing express-end with a more modern and less intrusive solution like on-finished, which provides a callback when the response finishes or the client disconnects.
breaking This package is explicitly designed for very old Node.js versions (engines: '>=0.10') and has not been updated since 2016. It is highly incompatible with modern Node.js (e.g., 16+) and Express. Running it in a modern environment will likely cause errors or unexpected behavior.
fix Do not use this package in modern Node.js or Express applications. Seek modern alternatives or implement custom event emission if absolutely necessary.
gotcha The middleware achieves its functionality by monkey-patching `res.end()`. This is an inherently fragile technique that can lead to conflicts with other middleware, Express internal changes, or unexpected side effects, especially in complex applications or when using other response-modifying libraries.
fix Avoid monkey-patching where possible. If a similar functionality is needed, consider using libraries like `on-finished` which provide a more robust way to detect response completion, or implement a pattern that doesn't modify core Express objects directly.
deprecated The problem this package aims to solve (the `finish` event not firing when a client disconnects prematurely) might be handled differently or natively improved in newer versions of Express or related Node.js modules. Relying on this package for modern applications is considered an anti-pattern.
fix Investigate if newer Express versions (e.g., 4.x and above) provide better event handling or if alternative packages like `on-finished` offer a more reliable solution for detecting when a response has fully completed its server-side processing.
npm install express-end
yarn add express-end
pnpm add express-end

This example demonstrates how to integrate `express-end` middleware and listen for the custom `end` event alongside standard `close` and `finish` events on the response object, showing how `end` fires consistently.

'use strict';

const express = require('express');
const http    = require('http');
const endMw = require('express-end');
const app = express();

app.use(endMw);

let count = 0;

app.use(function(req, res, next) {
  const current = ++count;
  console.log('[%d] app.use()', current);

  res.once('close',  function() {
    console.log('[%d] app.use(): res.once(close)', current);
  });

  res.once('end',    function() {
    console.log('[%d] app.use(): res.once(end)', current);
  });

  res.once('finish', function() {
    console.log('[%d] app.use(): res.once(finish)', current);
  });

  next();
});


const httpPort = 8080;
const RESPONSE_DELAY = 1000; // Milliseconds

app.get('/test1', function (req, res) {
  const result = { test: 'test' };
  setTimeout(function() {
    res
      .status(200)
      .send(result);
  }, RESPONSE_DELAY);
});


const server = http.createServer(app);

server.listen(httpPort, function () {
  console.log('* Server listening at %s:%d', server.address().address, server.address().port);
});