Closed
Description
Describe the bug
Using axios version 1.18.0, running the following mocha test, where the timeout is specified, results with:
Got the expected error: timeout of 200ms exceeded
✓ test axios (210ms)
1 passing (217ms)
Using axios version 1.19.x, running the same mocha test would result with
1) test axios
0 passing (1s)
1 failing
1) test axios:
Error: drp. this happens instead
at Timeout._onTimeout (src/subscriptions-manager/axios-test.js:24:14)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
To Reproduce
run with mocha
const axios = require('axios');
const invalidUrl = 'http://12.12.12.12:123/arf/arf';
const postToInvalidUrl = async () => {
return new Promise((resolve, reject) => {
axios({
url: invalidUrl,
method: 'post',
data: {not: 'relevant'},
timeout: 200,
})
.then(() => {
reject(new Error('success should"t happen'));
})
.catch(err => {
console.log('Got the expected error: ', err.message);
resolve();
});
setTimeout(function () {
reject(new Error('drp. this happens instead'));
}, 1000);
});
};
it('test axios', async () => {
await postToInvalidUrl();
});
Expected behavior
that the behavior from 0.18.0 would be preserved
Activity
chinesedfan commentedon Feb 4, 2020
Don't remember we changed something related to timeout. I saw it once in codesandbox and it can't be reproducible any more, no matter in local test or https://codesandbox.io/s/axios2710-bgphy. Can you confirm it is always the same result with different timeout values?
fresidue commentedon Feb 4, 2020
Yes it is consistent for different values of timeout. However, the break in behavior seems to occur between 0.19.0 and 0.19.1 (i.e. the timeout value is respected for 0.19.0)
chinesedfan commentedon Feb 4, 2020
@fresidue Can you provide the required information in the issue template? My codesandbox confirms your conclusion, which uses Node.js 10.17.0. But the local environment(OSX 10.14.5, Node.js 10.17.0) always works well.
tblasche commentedon Mar 16, 2020
The timeout functionality breaks with https://github.com/axios/axios/pull/1752/files in axios v0.19.1
This is a pretty problematic bug. If URL is an IP address which is not reachable, the timeout will not be respected.
fishcharlie commentedon Mar 23, 2020
@chinesedfan I'm running into this as well. I tried to provide the requested information below. Let me know if there is anything I can do to help get this fixed.
0.19.2
works as expected in0.18.1
chinesedfan commentedon Mar 28, 2020
@fishcharlie According to @tblasche's discovery, it seems to be due to req.setTimeout. So this is an upstream problem. Can you or someone to check issues of Node.js?
fishcharlie commentedon Mar 28, 2020
@chinesedfan I'm not finding anything on the Node.js issue section regarding this. I found a few similar things, but they didn't look like the same thing.
I'd be happy to submit an issue and help try to move this forward. My only concern is that I don't have as much knowledge as some of the others here in terms of the story behind this issue an associated PR.
I'm also not sure that we have a concrete failing example that is simple and easy to reproduce. Which makes it harder since anyone looking at the issue will have to dig through the axios codebase.
Any thoughts on how to proceed? Would love to help get this fixed ASAP, but just want to make sure we are all on the same page, and I know I'm slightly more limited in my knowledge level about this.
chinesedfan commentedon Mar 29, 2020
@fishcharlie That's really what we need. Once confirmed, we can open an issue to Node.js.
The sample can be extracted from
lib/adapters/http.js
, which is a simple request based on Node.js http module. You can write two cases. One is usingsetTimeout
like axios v0.18, and the other is like #1752.fishcharlie commentedon Mar 29, 2020
@chinesedfan I was only able to reproduce this error when using the NPM package nock, under very specific conditions. Took me a while to get a failing example. Below you can find the most minimal code I was able to use to recreate the problem.
I attempted to create this also with an Express server that just doesn't send any response, and was unable to reproduce that. So I'm wondering if there is something else going on behind the scenes with like the connection or something.
If you think this all looks good I will open an issue on the
nodejs/node
repository. But I'm still unsure if there is something else about how nock handles things that I need to investigate further first. But that might be past my expertise level at this point.Let me know what your thoughts are.
Working Code
Failing Code
mooyoul commentedon Mar 29, 2020
This issue is called as "Call Timeout".
From request's README:
HTTPRequest#setTimeout
callsSocket#setTimeout
internally, which only tracks "socket inactivity". socket timer will be reset if any socket activity were detected.according to documentation:
so, if socket timeout is 1000ms and server sends packets per each 800ms, socket won't trigger timeout event.
Here's quick reproducible codesandbox project:
https://codesandbox.io/s/keen-surf-07ibg
Please take a look into
request
's source - Read Timeouts has been handled by creating internal timers.mooyoul commentedon Mar 29, 2020
Quick & Dirty workaround at this moment:
fishcharlie commentedon Mar 29, 2020
@chinesedfan Wasn’t the reason for this change (and not using setTimeout/internal timers) due to a security vulnerability? Wouldn’t the code @mooyoul just suggested have that same security vulnerability?
34 remaining items