Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express.js connect timeout vs server timeout

I am using express and Connect Timeout Middleware to handle the timeouts.

It works great, but I the default node http server's timeout is set to two minutes.

Therefore if I want to set my timeout middleware to a value greater than two minutes, I also have to increase the http server timeout to be slightly bigger (otherwise my connect timeout handler is not called)

const app = express();
const http = new Http.Server(app);

http.setTimeout((4 * 60 * 1000) + 1); <-- Must set this

app.use(timeout('4m')); 

How can I avoid this ? Am I missing something ?

like image 207
Scaraux Avatar asked Mar 26 '19 18:03

Scaraux


People also ask

What is Express default timeout?

By default, normal HTTP requests to Node. js/Express/Sails. js apps time out after 2 minutes (120000 milliseconds) if a response is not sent.

How do I increase my Express timeout?

Simply put, you need to configure the timeout value on the HTTP Server that express generates when you call the listen method. For example: // create an express app const app = express(); // add a route that delays response for 3 minutes app. get('/test', (req, res) => { setTimeout(() => { res.

Is Express js still used 2021?

Express is currently, and for many years, the de-facto library in the Node. js ecosystem. When you are looking for any tutorial to learn Node, Express is presented and taught to people.


1 Answers

If you want to use the connect-timeout middleware, you can't avoid it, since the middleware does not change the socket timeout, which defaults to 2 minutes.

There are two possible ways to avoid it, either using server.setTimeout() or request.setTimeout.

In case you only want to change the timeout to a few routes, and leave the default timeout to the rest, the recommended approach is to use: request.setTimeout

app.use('/some-routes', (req, res, next) => {
   req.setTimeout((4 * 60 * 1000) + 1);
   next();
}, timeout('4m'));

An alternative to setting the req.setTimeout to a value greater than the connect-timeout value, is dropping the connect-timeout middleware and using another work around, which is also not ideal.

You can check this old Node.js issue https://github.com/nodejs/node-v0.x-archive/issues/3460

function haltOnTimedout (req, res, next) {
  if (!req.timedout) next()
}

app.use('/some-routes', (req, res, next) => {
    req.setTimeout(4 * 60 * 1000); // No need to offset

    req.socket.removeAllListeners('timeout'); // This is the work around
    req.socket.once('timeout', () => {
        req.timedout = true;
        res.status(504).send('Timeout');
    });

    next();
});


app.use(haltOnTimedout);

// But if the timeout occurs in the middle of a route
// You will need to check if the headers were sent or if the request timedout

app.get('/some-routes', async(req, res, next) => {
  
  // some async processing...
  await asyncOperation();
  
  if (!res.headersSent) // or !req.timedout 
    res.send('done');
 
});
like image 167
Marcos Casagrande Avatar answered Oct 17 '22 05:10

Marcos Casagrande