Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJS http get timeout

I have the following code which is creating issues:

var timeout_wrapper = function (req) {
    return function () {
        log.error('rest', 'Unable to contact service. Timed out.');
        if (res.req) {
            res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Timed out contacting service.');
        }

        req.abort();
    };
};

var timeout;

var req = https.get(options, function (response) {
    log.info('rest', 'Got response from service.');
    clearTimeout(timeout);

    if (response.statusCode === HttpStatus.NOT_FOUND) {
        callback(false);
        return;
    }
    if (response.statusCode === HttpStatus.NO_CONTENT) {
        callback(true);
        return;
    }

    log.error('rest', 'Service returned an undocumented status code: %s', response.statusCode);
    res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Unable to contact service.');
}).on('error', function (e) {
    clearTimeout(timeout);

    log.error('rest', 'Unable to contact service. Got error: %s', e);
    /*if (res.req) {
        res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Unable to contact service.');
    }*/
});

timeout = setTimeout(timeout_wrapper(req), 10000);

The service I am contacting is timing out quite often (but I have no control over that). So I created a timeout function, which works (the client is indeed receiving res.status(HttpStatus.INTERNAL_SERVER_ERROR).send('Timed out contacting service.'); ), but the request is not aborted. The .on('error', ...) is called a while after with the following stacktrace:

ERR! rest  Error: socket hang up
ERR! rest     at createHangUpError (http.js:1472:15)
ERR! rest     at CleartextStream.socketCloseListener (http.js:1522:23)
ERR! rest     at CleartextStream.EventEmitter.emit (events.js:117:20)
ERR! rest     at tls.js:696:10
ERR! rest     at process._tickCallback (node.js:415:13)
ERR! rest  Unable to contact service. Got error: %s { [Error: socket hang up] code: 'ECONNRESET' }

I thought this was a simple HTTPS GET request, not a socket, and why is the request not aborted in my timeout function?

like image 760
Nepoxx Avatar asked Feb 01 '26 22:02

Nepoxx


1 Answers

I don't think you need crate a timeout_wrapper for this situation. A simple solution would be put http.get inside a function with a callback as parameter. This one may not be flexible as your solution, but looks simpler and should work in this situation.

function testGet(options, callback) {
    var req = http.get(options, function(response) {

        if (response.statusCode === HttpStatus.NOT_FOUND)
           callback(false);

        if (response.statusCode === HttpStatus.NO_CONTENT)
           callback(true);

        if (response.statusCode == ERROR)
           callback(false);

    }).on('error', function(e){
        callback(false);
    });

    req.setTimeout(TIMEOUT, function(){
        callback(false);
        req.abort();
    }
}
like image 138
aracyla Avatar answered Feb 04 '26 12:02

aracyla



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!