JoséMi
JoséMi

Reputation: 11952

NodeJS http post request read timeout

I'm trying to execute the following code inside AWS Lambda which only makes a POST http request to an ElasticSearch.

The problem I'm facing is that it seems the nodejs request has a read timeout and the response is almost always cut and an error is thrown. I've checked that the problem is not related with AWS Lambda timeout which is set to 10 seconds and the code throws an error in less than a second.

As you can see, I've tried to put a timeout to 5secs but I think that's a connection timeout and not a read timeout.

What am I doing wrong?

var http = require('http');

exports.handler = (event, context, callback) => {

var options = {
    hostname: '172.31.40.10',
    port: 9200,
    path: '/articles/es/_search?_source=reference',
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    }
};
var req = http.request(options, function(res) {
    res.setEncoding('utf8');
    res.on('data', function (body) {
        var parsed = JSON.parse(body);
        var b = [];
        for (var i = 0; i < parsed.hits.hits.length; i++) {
            b.push(parsed.hits.hits[i]._source.reference);
        }
        var response = {
            statusCode: '200',
            body: JSON.stringify(b),
            headers: {
                'Content-Type': 'application/json',
            }
        };            
        callback(null, response);
    });
});
req.on('error', function(e) {
    callback(new Error('fallo'));
});
req.setTimeout(5000, function() {req.abort;})
req.on('socket', function (socket) {
    socket.setTimeout(5000);  
    socket.on('timeout', function() {
        req.abort();
    });
});    

req.write(MY_QUERY_HERE);
req.end();    
};

Upvotes: 3

Views: 2301

Answers (1)

EMX
EMX

Reputation: 6211

I think you should let the stream of incoming data finish before performing any data manipulation.

Example :

var http = require('http');
//var _ = require('underscore');
function MyPostRequest(callback) {
 var options = {
  hostname:'172.31.40.10',
  port:9200,
  path:'/articles/es/_search?_source=reference',
  method:'POST',
  headers:{'Content-Type':'application/json'}
 };
 http.request(options, function(res) {
  var tmpstore = ''; //temp. data storage
  //:Store the continuous incoming data stream 
  res.on('data', function(d){tmpstore += d;});
  //:Data reception is done, use it now...
  res.on('end', function() {
    var parsed = JSON.parse(tmpstore); var b = [];
    for (var i = 0; i < parsed.hits.hits.length; i++) {
      b.push(parsed.hits.hits[i]._source.reference);
    }
/*  //I suggest using underscore module :
    _.each(parsed.hits.hits,function(element, index, list){
      b.push(element._source.reference);
    });
*/
    var response = {
      statusCode:'200',
      body:JSON.stringify(b),
      headers:{'Content-Type':'application/json'}
    };            
    callback(null, response);
  });
  //:Response contained an error
    res.on('error', function(e){/*error handling*/callback(e,null);});
 });
}

Upvotes: 1

Related Questions