Reputation: 5046
PROBLEM
I've been looking for request/response timeouts for Express.js but everything seems to be related to the connection rather than the request/response itself.
If a request is taking a long time, it should be timed out. Obviously this shouldn't happen but even a simple mistake as having a route handler without a call to the callback or without res.send()
, the browser will keep waiting for a reply forever.
An empty route handler is a perfect example of this.
app.get('/sessions/', function(req, res, callback){});
FIX
I added the following before app.use(app,router);
and it seemed to add the timeout functionality. Does anyone have any experience/opinion on this?
app.use(function(req, res, next){
res.setTimeout(120000, function(){
console.log('Request has timed out.');
res.send(408);
});
next();
});
Note that I've set the timeout to 2 minutes.
Upvotes: 111
Views: 228766
Reputation: 1034
I hope it's not too late, this is a solution that I got from @Elliot404, and it's what I was looking for. I hope it helps.
export const timeOutMiddleWare = (
req: Request,
res: Response,
next: NextFunction,
) => {
setTimeout(() => {
if (!res.headersSent) {
res.status(408).send(`${req.method} ${req.originalUrl} Timed Out`);
req.socket.end();
res.json = () => {};
res.send = () => {};
res.sendStatus = () => {};
}
}, 1000 * 60 * 5);
next();
};
Upvotes: 0
Reputation: 91
If you need to test your api, this solotion can you help. I used this in middleware to test my frontend. For exmaple: if you need to test loader in frontend.
const router = require('express').Router();
const { data } = require('./data');
router.get('/api/data', (req, res, next) => {
setTimeout(() => {
res.set('Content-Type', 'application/json')
res.status(200).send(data)
next()
}, 2000)
})
module.exports = router;
Upvotes: 1
Reputation: 702
You can try:
return await new Promise((resolve) =>
setTimeout(() => {
resolve(resp);
}, 3000),
);
In above code, 3000 = 3 sec. Change it according to your requirement.
I have not tried for very long scenarios though. Let me know the results in comments.
Upvotes: -4
Reputation: 13016
var server = app.listen();
server.setTimeout(500000);
inspired by https://github.com/expressjs/express/issues/3330
or
app.use(function(req, res, next){
req.setTimeout(500000, function(){
// call back function is called when request timed out.
});
next();
});
Upvotes: 88
Reputation: 407
In case you would like to use timeout middleware and exclude a specific route:
var timeout = require('connect-timeout');
app.use(timeout('5s')); //set 5s timeout for all requests
app.use('/my_route', function(req, res, next) {
req.clearTimeout(); // clear request timeout
req.setTimeout(20000); //set a 20s timeout for this request
next();
}).get('/my_route', function(req, res) {
//do something that takes a long time
});
Upvotes: 5
Reputation: 253
request.setTimeout(< time in milliseconds >)
does the job
https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback
Upvotes: 0
Reputation: 7666
An update if one is using Express 4.2 then the timeout middleware has been removed so need to manually add it with
npm install connect-timeout
and in the code it has to be (Edited as per comment, how to include it in the code)
var timeout = require('connect-timeout');
app.use(timeout('100s'));
Upvotes: 37
Reputation: 57
Before you set your routes, add the code:
app.all('*', function(req, res, next) {
setTimeout(function() {
next();
}, 120000); // 120 seconds
});
Upvotes: -21
Reputation: 10501
There is already a Connect Middleware for Timeout support:
var timeout = express.timeout // express v3 and below
var timeout = require('connect-timeout'); //express v4
app.use(timeout(120000));
app.use(haltOnTimedout);
function haltOnTimedout(req, res, next){
if (!req.timedout) next();
}
If you plan on using the Timeout middleware as a top-level middleware like above, the haltOnTimedOut
middleware needs to be the last middleware defined in the stack and is used for catching the timeout event. Thanks @Aichholzer for the update.
Keep in mind that if you roll your own timeout middleware, 4xx status codes are for client errors and 5xx are for server errors. 408s are reserved for when:
The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time.
Upvotes: 90