Express.js Response Timeout
Solution 1
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.
Side Note:
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.
Solution 2
You don't need other npm modules to do this
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();
});
Solution 3
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'));
Solution 4
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
});
Related videos on Youtube
Xerri
Updated on July 08, 2022Comments
-
Xerri almost 2 years
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.
-
srquinn over 10 yearsI would use this for development purposes only – I can't think of a single use case where you would want to ship production code with empty routes.
-
Xerri over 10 yearsIf course, my point with that is that its possible to have an issue where the request would just keep waiting. Bugs happen. I'm just trying to set a response timeout just in case.
-
srquinn over 10 yearsGotcha – see answer below
-
prototype over 8 yearsempty routes as a trap for web spiders?
-
Ferenc Dósa-Rácz about 6 yearsThis 'feature' actually came quite useful when I was trying to use Express.js (well, actually json-server) to build a test service with the purpose of simulating / inducing all manners of error conditions on the server side. Most such errors corresponded to HTTP status codes (e.g. Bad Request), yes, but I also wanted to cause a SocketTimeoutException on the caller end.
-
欧阳维杰 about 6 yearswhat will happen if the value of response timeout is large then the http's timeout?
-
-
Xerri over 10 yearsPerfect. Even simpler. Thanks for the tip on the error message as well.
-
Stefan over 9 yearsAccording to the official documentation, using it as top-level middleware is not recommended, at least not just like that. github.com/expressjs/timeout
-
Jeff Fischer over 9 yearsThis answer seems to be fairly useless without increasing the socket timeout. stackoverflow.com/questions/12651466/…
-
srquinn over 9 years@JeffFischer: calling
socket.setTimeout()
only increases the time before the timeout event is called but the connection is not severed by default nodejs.org/api/net.html#net_socket_settimeout_timeout_callback. In node v0.9.12, a setTimeout API was added to thehttp.server
object to handle the functionality of this middleware in the node standard http lib. However, before that API update this middleware would handle destroying the socket. You can read more on the innards of the middleware here github.com/expressjs/timeout/blob/master/index.js -
SuperUberDuper almost 8 yearsI have the following app.get('/timeout', function (req, res) { for (var i = 0; i < 1111211111; i++) {} res.send('d') }) but I always get d back, why?, Note, I'm using app.use(timeout('1s'));
-
srquinn almost 8 years@SuperUberDuper: Please post you query as a separate question so the community can help you with your specific issue.
-
SuperUberDuper almost 8 yearssure mate: stackoverflow.com/questions/37787255/…
-
Jeffrey van Norden almost 7 yearsIsn't this just waiting for 120 second before ever replying to the client?
-
Mohamed Salad about 6 yearsDidn't DV, but some people probably need to use var timeout = require('connect-timeout') and had to search google for it =)
-
Xerri over 5 yearsThis is a very old post but I didn’t use any extra modules. Check out the ‘fix’ part in the question
-
5ervant - techintel.github.io about 5 years
Error: Cannot find module 'connect-timeout'
-
5ervant - techintel.github.io about 5 years@JeffreyvanNorden That's what I'm looking for, for debugging purpose.
-
Farasi78 over 3 years@5ervant use $ npm install connect-timeout here is a link to documentation expressjs.com/en/resources/middleware/timeout.html
-
DollarAkshay about 3 years
req.setTimeout
notres.setTimeout
-
Slava Fomin II almost 3 yearsMy experiments show that
req.setTimeout()
callback is not getting called at all and theserver.setTimeout()
is not closing the connection and is not stopping the request from being processed. So the provided solution is not complete. -
Michael Cox over 2 yearsMy test have
req.setTimeout
andres.setTimeout
both working. -
AndrewLeonardi over 2 yearsIronically this is exactly what I was looking for.
-
Paul Fabbroni about 2 yearsres.setTimeout worked for me not req