I'm looking at switching from request to got due to massive amount of bloat. It looks like timeouts don't behave the same way in got and am wondering what the issue is.
Versions: got v6.3.0 on node.js v6.3.1.
const got = require('got');
const url = 'http://10.155.155.155';
const options = {
timeout: 500
};
got(url, options).then(function(res) {
console.log(res.body);
}).catch(function (err) {
console.error(err);
})
const rp = require('request-promise');
const rpOptions = {
'http://10.155.155.155',
timeout: 500
};
rp(rpOptions).then(function(res) {
console.log(res.body);
}).catch(function (err) {
console.error(err);
})
{ RequestError: Error: ETIMEDOUT
at new RequestError (request-promise/lib/errors.js:11:15)
at Request.RP$callback [as _callback] (request-promise/lib/rp.js:60:32)
at self.callback (request/request.js:187:22)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at Timeout._onTimeout (request/request.js:762:12)
at tryOnTimeout (timers.js:224:11)
at Timer.listOnTimeout (timers.js:198:5)
name: 'RequestError',
message: 'Error: ETIMEDOUT',
cause:
{ Error: ETIMEDOUT
at Timeout._onTimeout (request/request.js:759:15)
at tryOnTimeout (timers.js:224:11)
at Timer.listOnTimeout (timers.js:198:5) code: 'ETIMEDOUT', connect: true },
error:
{ Error: ETIMEDOUT
at Timeout._onTimeout (request/request.js:759:15)
at tryOnTimeout (timers.js:224:11)
at Timer.listOnTimeout (timers.js:198:5) code: 'ETIMEDOUT', connect: true },
options:
{ url: 'http://10.155.155.155',
timeout: 500,
callback: undefined,
transform: undefined,
simple: true,
resolveWithFullResponse: false },
response: undefined }
Note that the IP is just some garbage IP address that is not assigned to anything. Any help would be appreciated. Thanks!
I should also note that needle (another minimal HTTP request library I am looking at) does timeouts correctly as well.
// note that I manually promisified this code, which isn't shown
const url = 'http://10.155.155.155';
const options = {
timeout: 500
};
needle.get(url, options).then(function(res) {
console.log(res.body);
}).catch(function (err) {
console.error(err);
})
Output:
{ Error: socket hang up
at createHangUpError (_http_client.js:252:15)
at Socket.socketCloseListener (_http_client.js:284:23)
at emitOne (events.js:101:20)
at Socket.emit (events.js:188:7)
at TCP._handle.close [as _onclose] (net.js:492:12) code: 'ECONNRESET' }
@MarkHerhold ETIMEDOUT error is whitelisted for retrying – so setting retries: 0 fixes your issue.
Ah! Novice mistake. Thanks @floatdrop
Please write about it in documentation. It's totally unclear.
Still an issue. Timeout is not respected when it is greater than 1000ms.
const got = require('got');
const url = 'http://10.15.15.234';
const options = {
timeout: 1000,
retries: 0
};
got(url, options).then(function(res) {
console.log(res.body);
}).catch(function (err) {
console.error(err);
})
Reopening for @pasupulaphani
@pasupulaphani can you tell, what is expected? I've tested this with added console.time and it gives me 1015.766ms before firing error.
@floatdrop Sorry for the false alarm. Looks like I made mistake. Not a bug.
Can you provide a full example how to make timeouts work properly without retries?
The following code takes ~8 secs to run:
const got = require('got');
const url = 'http://10.155.155.155';
const options = {
timeout: 500,
retry: 0
};
const t0 = Date.now();
got(url, options).then(function(res) {
console.log(res.body);
}).catch(function (err) {
console.error(err);
console.log("Took " + (Date.now() - t0) + " ms")
})
I've also tried retry: { retries: 0 } and retries: 0 and haven't been able to reduce the timeout.
This gotcha! should be mentioned also in the documentation for timeout - if I say timeout: 1000 I expect it to take max 1 second.
@plaa it's retry and not retries
'use strict';
const { expect } = require('chai');
const net = require('net');
const got = require('got');
let mockServer;
describe('Patch for request', () => {
// start mock server
before((done) => {
mockServer = net.createServer(() => {
// Never send a reponse to simulate a timeout
});
mockServer.listen(10101, done);
});
after((done) => {
mockServer.close(done);
});
it('should return an error after the timeout of 500ms', (done) => {
const t0 = Date.now();
got('https://10.155.155.155',{
timeout: 500,
retry: 0
}).catch(err => {
console.log('Took ' + (Date.now() - t0) + ' ms');
expect(err).to.exist;
expect(err).to.have.property('code').that.equals('ETIMEDOUT');
expect(err).to.have.property('message').that.includes('Timeout awaiting \'request\' for 500ms');
done();
});
});
it('should return an error after the timeout of 500ms', (done) => {
const t0 = Date.now();
got('https://10.155.155.155',{
timeout: 1500,
retry: 0
}).catch(err => {
console.log('Took ' + (Date.now() - t0) + ' ms');
expect(err).to.exist;
expect(err).to.have.property('code').that.equals('ETIMEDOUT');
expect(err).to.have.property('message').that.includes('Timeout awaiting \'request\' for 1500ms');
done();
});
});
});
result
Took 525 ms and Took 1501 ms
Most helpful comment
Please write about it in documentation. It's totally unclear.