Search code examples
node.jsexpressconnect-timeout

Express middleware "connect-timeout" causes "Can't set headers after they are sent."


My code:

timeout = require('connect-timeout')

app.get('/', timeout('5s'), function(req, res){
  ##DO SOMETHING 1
  ##DO SOMETHING 2
  ##DO SOMETHING 3
  res.send('ok'); ##line 7
});

When user requesting. Node.js processes "DO SOMETHING1-3". But before it processed. Timeout middleware response because it has been set for 5 seconds. After that in line 7 routing try to response again. And Its causes Error "Can't set headers after they are sent."

How to handle the problem ?


Solution

  • I had a feeling this would be a common problem, so I searched the GitHub repository and found this issue.

    In this answer, I will outline the two possible solutions proposed in the issue I linked above:

    1. You could check to see if the request has timed out via the req.timedout property before calling res.send:

      app.get('/', timeout('5s'), function(req, res){
        ##DO SOMETHING 1
        ##DO SOMETHING 2
        ##DO SOMETHING 3
        if (!req.timedout) {
          res.send('ok'); ##line 7
        }
      });
      
    2. Or you could mount some top-level middleware which effectively suppresses the error:

      app.use(function(req,res,next){
        var _send = res.send;
        var sent = false;
        res.send = function(data){
            if(sent) return;
            _send.bind(res)(data);
            sent = true;
        };
        next();
      });