Voles Voles - 2 months ago 21
Node.js Question

Node Express specific timeout value per route

I'm developing a Node v4.2.4 application using Express v4.13.4. Now I would like to increase the timeout time for a specific upload route.

From what I've read and experienced:



However, I'm lost when trying to implement the connect-timeout middleware for the upload route.

Application setup

const app = express();
app.use(cors());
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: false }));
app.use(passport.initialize());

app.use('/uploads', uploadRoutes);
app.use(errorHandler);

function errorHandler(err, req, res, next) {
if (err.code && err.code === 'ETIMEDOUT') {
if (!res.headersSent) {
res
.status(408)
.send({
success: true,
message: 'Timeout error'
});
}
}

next(err);
}

const server = app.listen(config.port);


Upload route definition

router.route('/:uploadId/upload-files')
.post(timeout('3m'),
require('./actions/upload-files').prepareHandler,
require('./actions/upload-files').uploadHandler(),
require('./actions/upload-files').responseHandler);


However, when uploading the files I do see the error from
express-timeout
after 3 minutes ONLY in the command line's console. The request is still in progress and no status code of 408 is returned.

After 4 minutes I finally see the 408 status and 'Timeout error' as part of the response object.

For requests to other routes I get the
net::ERR_EMPTY_RESPONSE
error after 4 minutes.

If I log the value for
server.timeout
, the value is
120000
(2 minutes).

My questions


  • where can the 4 minutes possible come from? Is it because there's a preceding OPTIONS request maybe?

  • what's the difference between server & socket timeouts and how to set them properly for a specific route?


Answer

I've solved it using the following route configuration:

'use strict';

const ms = require('ms');
const express = require('express');
const router = express.Router();

router.route('/upload-files')
  .post(
    setConnectionTimeout('12h'),
    require('./actions/upload-files').responseHandler
  );

function setConnectionTimeout(time) {
  var delay = typeof time === 'string'
    ? ms(time)
    : Number(time || 5000);

  return function (req, res, next) {
    res.connection.setTimeout(delay);
    next();
  }
}

exports.router = router;

Where the key logic is the following middleware:

  function (req, res, next) {
    res.connection.setTimeout(delay);
    next();
  }

I hope this reference will come in handy for others.