2

In my AWS Lambda Node.js code, I've following code that calls the post method to index a document to AWS Elasticsearch service:

var endpoint = 'ABC-XYZ.us-east-1.es.amazonaws.com';

exports.handler = function(input, context) {
    ...

    // post documents to the Amazon Elasticsearch Service
    post(endpoint, elasticsearchBulkData, function(error, success, statusCode, failedItems) {
        if (error) {
          console.log('...');

          if (failedItems && failedItems.length > 0) {
            console.log(...);
          }

          // NOTE: Instead of failing, we are forcing a success, as we do not want retries
          context.succeed('Success');
        } else {
          // console.log('Success: ' + JSON.stringify(success));
          context.succeed('Success');
        }
      });
    }

   ...
   ...
function post(endpoint, body, callback, lastTimeout) {
  lastTimeout || (lastTimeout = 500);
  var requestParams = buildRequest(endpoint, body);

  var request = https.request(requestParams, function(response) {
    var responseBody = '';
    response.on('data', function(chunk) {
      responseBody += chunk;
    });
    response.on('end', function() {
      var info = JSON.parse(responseBody);
      var failedItems;
      var success;

      if (response.statusCode >= 200 && response.statusCode < 299) {
        failedItems = info.items.filter(function(x) {
          return x.index.status >= 300;
        });

        success = { ...};
      }

      var error = response.statusCode !== 200 || info.errors === true ? {
        "statusCode": response.statusCode,
        "responseBody": responseBody
      } : null;

      callback(error, success, response.statusCode, failedItems);
    });
  }).on('error', function(e) {
    console.error(e.stack || e);
    //callback(e);
    lastTimeout *= 2;
    console.log('lastTimeout: ' + lastTimeout + " for cluster: " + endpoint) ;
    setTimeout(function() {
      post(endpoint, body, callback, lastTimeout);
    }, lastTimeout);
  });
  request.end(requestParams.body);
}

...

At times I get Error: socket hang up ECONNRESET.

My question is: What would be the best way to catch this error and retry?

I added the setTimeout snippet based on this answer and it looks like it does work but I'm not sure if that's the right way to do.

Node.js version is 4.3.

I was thinking of using Promise with resolve and reject but being a JS Newbie, I'm not sure how to make use of promise in my post call.

I also went through this link but not clear on how can I wrap my post call with fetch_retry

Sandeep Kanabar
  • 1,264
  • 17
  • 33

1 Answers1

2

I have a node application that, from time to time throws an exception that I can not catch:

Error: read ECONNRESET at TLSWrap.onread (net.js:622:25)

I don't know if it's related to your issue, but it seems so. After some research it seems that is a bug: https://github.com/nodejs/node/issues/23237 and it has been addressed in the last version.

Right now I am running node version 8, and I have noticed that you are using version 4. I will update the production server in the near future, maybe you can try that also. If the question does not have an answer until I have updated my server, I will come back here with the results.

Cosmin Staicu
  • 1,809
  • 2
  • 20
  • 27
  • 1
    Thanks. Unfortunately, i can't upgrade to 8 coz it could break a lot of stuff of other people. For me, the problem happened because the Lambda was indexing to 2 different ES clusters and the solution lay in setting the `context.succeed` ONLY after BOTH the post requests had succeeded. Setting `context.succeed` before the 2nd post had succeeded will invalidate the connection handler – Sandeep Kanabar Feb 21 '19 at 01:24