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?
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With