{"id":17982,"library":"timeout-middleware","title":"Express Request Timeout Middleware","description":"This package, `timeout-middleware` (current version 0.6.1), provides an Express.js middleware designed to gracefully handle slow requests by enforcing a response timeout. It intercepts `res.status`, `res.sendStatus`, and `res.send` methods, checking a `res.timedout` flag before allowing further modifications to the response. Upon timeout, if headers have not yet been sent, it automatically sets the response status to 503 (Service Unavailable) and sends a 'Request Timeout' message. This approach differs from alternatives like `connect-timeout` which require manual `haltOnTimedout` checks after every middleware in the chain. The library aims for a more 'DRY' (Don't Repeat Yourself) implementation by wrapping the core response methods, preventing accidental operations on a timed-out request. As a pre-1.0 version, future API changes are possible, and its release cadence is not explicitly defined in the provided information.","status":"active","version":"0.6.1","language":"javascript","source_language":"en","source_url":"https://github.com/fjodorekstrom/timeout-middleware","tags":["javascript","node","express","timeout","request"],"install":[{"cmd":"npm install timeout-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add timeout-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add timeout-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for an Express.js middleware.","package":"express","optional":false}],"imports":[{"note":"The package uses ES module syntax in its README, suggesting ESM-first usage, though CommonJS `require` might work with transpilation or specific Node.js configurations.","wrong":"const timeout = require('timeout-middleware');","symbol":"default","correct":"import timeout from 'timeout-middleware';"},{"note":"The middleware is exported as a default export, not a named export.","wrong":"import { timeout } from 'timeout-middleware';","symbol":"timeout","correct":"import timeout from 'timeout-middleware';\napp.use(timeout(30000));"}],"quickstart":{"code":"import express from 'express';\nimport timeout from 'timeout-middleware';\n// In a real application, you'd install and use these\n// For demonstration, we'll mock them or simply omit them if not critical to timeout behavior\n// import bodyParser from 'body-parser';\n// import cookieParser from 'cookie-parser';\n\nconst app = express();\n\n// Apply the timeout middleware globally with a 2-second timeout\napp.use(timeout(2000)); \n\n// Simulate body-parser and cookie-parser if needed (or install them)\n// app.use(bodyParser.json());\n// app.use(cookieParser());\n\napp.get('/', (req, res) => {\n  res.send('Hello World!');\n});\n\napp.get('/slow', (req, res) => {\n  // Simulate a slow operation that exceeds the timeout\n  setTimeout(() => {\n    // This will not send 'Too late!' because the timeout middleware intercepted res.send\n    // and marked res.timedout = true, returning res instead of calling the original send.\n    res.send('Too late! This should not be sent.'); \n  }, 5000); // 5 seconds, which is longer than the 2-second timeout\n});\n\napp.get('/fast', (req, res) => {\n  setTimeout(() => {\n    res.status(200).send('This was fast enough.');\n  }, 500); // 0.5 seconds, which is faster than the 2-second timeout\n});\n\n// It's crucial to handle the 'error' event on the response object\n// to prevent Node.js from crashing if an unhandled error occurs.\napp.use((err, req, res, next) => {\n  console.error(err);\n  if (res.headersSent) {\n    return next(err); // Delegate to default Express error handler if headers were already sent\n  }\n  res.status(500).send('Something broke!');\n});\n\nconst PORT = process.env.PORT || 3000;\napp.listen(PORT, () => {\n  console.log(`Server listening on port ${PORT}`);\n  console.log('Try accessing /slow and /fast routes.');\n});","lang":"javascript","description":"Demonstrates how to apply the `timeout-middleware` globally and shows its effect on both fast and slow routes, preventing responses from being sent after a timeout. Includes basic error handling."},"warnings":[{"fix":"Always pin to exact versions (e.g., `\"timeout-middleware\": \"0.6.1\"`) and review release notes carefully when upgrading to avoid unexpected behavior.","message":"This package is currently at version 0.6.1, indicating it is pre-1.0. The API surface or core behavior may undergo breaking changes in future minor or major releases before a stable 1.0 version is reached.","severity":"breaking","affected_versions":">=0.x.x"},{"fix":"Ensure that any custom middleware or route handlers rely on the wrapped `res` methods and do not store references to the original `res` functions before `timeout-middleware` is applied. Place `timeout-middleware` high in your middleware chain.","message":"The middleware achieves its 'DRY' approach by wrapping and overriding `res.status`, `res.sendStatus`, and `res.send`. If other middleware or application code attempts to directly access or cache the *original* `res` methods after `timeout-middleware` has been applied, it might bypass the timeout check, leading to unexpected behavior or attempts to write to a timed-out response.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always include `res.on('error', err => { console.error(err); /* handle gracefully */ });` or implement a general Express error-handling middleware (`app.use((err, req, res, next) => { ... });`) to catch and manage errors gracefully without crashing the application.","message":"As `http.ServerResponse` (which Express `res` extends) is an EventEmitter, failure to add a listener for the `error` event can cause the Node.js process to crash if an error occurs during the response lifecycle. The README explicitly mentions this.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-23T00:00:00.000Z","next_check":"2026-07-22T00:00:00.000Z","problems":[{"fix":"Add an error listener to the `res` object within your middleware or a global Express error handler: `res.on('error', (err) => { console.error('Response error:', err); });`","cause":"The `res` object (an `EventEmitter`) emitted an error, and no listener was attached to handle it, causing the Node.js process to terminate.","error":"Unhandled 'error' event"},{"fix":"After any potentially long-running or asynchronous operation, always check `if (res.timedout || res.headersSent) return;` before attempting to send a response or set headers. This ensures that operations only proceed if the response is still open.","cause":"Although `timeout-middleware` attempts to prevent this by checking `res.headersSent`, some asynchronous operations in your route handler might attempt to write to the response after it has been implicitly or explicitly finalized (e.g., by the timeout middleware sending a 503 error) and its headers are already committed.","error":"Error: Can't set headers after they are sent."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}