1

I am using request module in Node JS (v8.12) to call a third party API. Since the API is not very reliable and due to lack of better option I am timing out the call after 2 seconds in case if there is no response from the API. But in doing so it creates a socket hang up error. Below is the code used and stack trace

const options = {
    url: resource_url,
    rejectUnauthorized: false,
    timeout: 2000,
    method: 'GET',
    headers: {
        'content-Type': 'application/json',
    }
};

return new Promise(function (resolve, reject) {
    request(options, function (err, res, body) {
        if (!err) {
            resolve(JSON.parse(body.data));                 
        } else {
            if (err.code === 'ETIMEDOUT' || err.code == 'ESOCKETTIMEDOUT') {
                resolve(someOldData);
            } else {
                resolve(someOldData);
            }
        }
    });
});


Error: socket hang up
    at createHangUpError (_http_client.js:331:15)
    at TLSSocket.socketCloseListener (_http_client.js:363:23)
    at scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:54:19)
    at Scope._activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/async_hooks.js:51:14)
    at Scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:12:19)
    at TLSSocket.bound (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:53:20)
    at emitOne (events.js:121:20)
    at TLSSocket.emit (events.js:211:7)
    at _handle.close (net.js:554:12)
    at TCP.done [as _onclose] (_tls_wrap.js:356:7)

After doing a bit of reading and research I found this article pointing out a similar issue so I switched to http module as mentioned in one of the solution in the article. But switching to http module also did not resolve the issue. Below is code implementation using http and stack trace.

let responseData;
const requestOptions = {
    hostname: resource_host,
    path: resource_path,
    method: 'GET',
    timeout: 2000,
};

return new Promise((resolve, reject) => {
    const requestObject = http.request(requestOptions, (responseObj) => {
        responseObj.setEncoding('utf8');
        responseObj.on('data', (body) => {          
           responseData = body;
        });

        responseObj.on('end', () => {
            resolve(responseData);
        });
    });

    requestObject.on('error', (err) => {
        responseData = someOldData;
        resolve(responseData);
    });

    requestObject.on('timeout', () => {
        responseData = someOldData;
        requestObject.abort();
    });

    requestObject.end();
});

Error: socket hang up
    at connResetException (internal/errors.js:608:14)
    at Socket.socketCloseListener (_http_client.js:400:25)
    at <trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:54:19
    at Scope._activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/async_hooks.js:51:14)
    at Scope.activate (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:12:19)
    at Socket.bound (<trace-log-base-path>/dd-trace/packages/dd-trace/src/scope/base.js:53:20)
    at Socket.emit (events.js:322:22)
    at Socket.EventEmitter.emit (domain.js:482:12)
    at TCP.<anonymous> (net.js:672:12)

I went through multiple SO post and various other resources over the web, but I am unable to resolve this issue.

Could it be because of the third party, because I also tried to reproduce the issue by creating a dummy server which sleeps for some time after the request is fired and timing out that request but was unable to reproduce the issue.

I'll be very grateful for any help in this regards.

Community
  • 1
  • 1
pythoniesta
  • 317
  • 6
  • 19
  • I'm facing the same issue. Were you able to resolve it ? It's possibly happening because of dd-trace library – Avijit Gupta May 18 '20 at 09:04
  • 1
    @AvijitGupta I was able to resolve it by using http module and removing *requestObject.abort();* in timeout event block – pythoniesta May 18 '20 at 09:21
  • Thanks for your answer and I'm glad it worked for you. In our case the we are not using the abort method anywhere. I'll see if I can find a fix for it soon. – Avijit Gupta May 18 '20 at 10:01

1 Answers1

1

Removing requestObject.abort() in timeout event block when using http module resolves this issue.

pythoniesta
  • 317
  • 6
  • 19