"Can't set headers after they are sent" error crashes the app
onlyjq04 opened this issue · comments
Hi,
When I use this middleware in my app I have encountered the following problem. (I elaborated in a test script):
const timeout = require('connect-timeout');
const express = require('express');
const app = express();
app.use(timeout(1 * 1000));
app.get('/test', (req, res) => {
setTimeout(function() {
res.send('triggered');
}, 2 * 1000);
});
app.listen(9988);
Then I got the error message and crashed the app:
curl -XGET http://localhost:9988/test
ServiceUnavailableError: Response timeout
at IncomingMessage.<anonymous> (/Users/yjq/testground/nodejs-test/node_modules/connect-timeout/index.js:84:8)
at emitOne (events.js:96:13)
at IncomingMessage.emit (events.js:188:7)
at Timeout._onTimeout (/Users/yjq/testground/nodejs-test/node_modules/connect-timeout/index.js:49:11)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
_http_outgoing.js:357
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11)
at ServerResponse.header (/Users/yjq/testground/nodejs-test/node_modules/express/lib/response.js:730:10)
at ServerResponse.send (/Users/yjq/testground/nodejs-test/node_modules/express/lib/response.js:170:12)
at Timeout._onTimeout (/Users/yjq/testground/nodejs-test/index.js:9:13)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5)
And then the app crashed
When you use this module, the purpose is to response. Since Node.js throws an error when you respond more than once, you always need to check req.timedout
before trying to send a response to know if you should or not. See the README for examples (Express.js example: https://github.com/expressjs/timeout#express-3x).