-
-
Notifications
You must be signed in to change notification settings - Fork 938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internal "options.timeout" is incompatible with the "timeout" option of "http.ClientRequest" #1579
Comments
Looks like a race condition in your project. console.log(requestOptions.timeout); right before Line 2415 in 8b88be2
szm@solus ~/Desktop/got $ npm run build && node demo.js
> got@11.8.0 build
> del-cli dist && tsc
undefined
node:internal/process/promises:225
triggerUncaughtException(err, true /* fromPromise */);
^
TypeError [ERR_INVALID_ARG_TYPE]: The "timeout" argument must be of type number. Received an instance of Object
at new NodeError (node:internal/errors:278:15)
at validateNumber (node:internal/validators:128:11)
at getTimerDuration (node:internal/timers:383:3)
at new ClientRequest (node:_http_client:173:20)
at request (node:http:50:10)
at Object.proxiedOriginalRequest (/home/szm/Desktop/got/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/index.js:55:36)
at ClientRequestOverride.<anonymous> (/home/szm/Desktop/got/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:249:39)
at step (/home/szm/Desktop/got/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:33:23)
at Object.next (/home/szm/Desktop/got/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:14:53)
at fulfilled (/home/szm/Desktop/got/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:5:58) {
code: 'ERR_INVALID_ARG_TYPE'
} |
That's right. If I remove Line 2423 in 8b88be2
and make got/source/core/utils/timed-out.ts Line 45 in 8b88be2
then I get
which assume is expected. |
I guess you don't clone the options, therefore modifying them results in an unexpected error. No such thing happens when running native Node.js. |
The culprit is here. You forgot to clone the options. |
Thank you for the suggestions, @szmarczak! Cloning the request options indeed helped. The behavior after cloning them, although doesn't involve
Somewhere along with the request life-cycle, there's a request to If I +import fetch from 'node-fetch'
-got(server.makeHttpUrl('/user'))
+fetch(server.makeHttpUrl('/user'))
Can it be that |
Your repo name is a red flag here: Are you modifying the default Node.JS request function (or Node.JS HTTP Agent)? |
I think I found the answer I was looking for
|
@Giotino, I believe you've found the correct answer. That repository is a library that provisions request interception in NodeJS. It works similarly to Nock, only with the inversed control over the mocked responses. I wish there was a better way to intercept requests in Node, but monkey-patching native modules is the only way there is now.
Modification of the native modules doesn't seem to be affecting anything for this issue: as I've mentioned above, the code works fine using |
@sindresorhus @Giotino I have investigated and it turns out the bug is on the interceptor side. |
Once more huge thanks to @szmarczak. The issue has been investigated and resolved. No changes on |
For future reference, the |
Describe the bug
Actual behavior
Hey 👋 I'm one of the maintainers of MSW, an API mocking library. Some of our users have reported a type error when using MSW and Got for requests interception in NodeJS (see mswjs/interceptors#86). I've investigated the issue and tracked it down to
got
source code, with which I'd kindly ask for your help.The internal
options.timeout
seems to represent a map of differents timeouts ("request", "socket", "lookup", "connect", etc.), which can be observed in how that option is handled when it's passed to thetimed-out.js
utility as thedelays
argument.Here's the journey of the
options.timeout
property:got/source/index.ts
Line 43 in 8b88be2
During the
_makeRequest
function thetimeout
option gets deleted and restored:got/source/core/index.ts
Lines 2421 to 2424 in 8b88be2
got/source/core/index.ts
Lines 2364 to 2366 in 8b88be2
Eventually, it gets passed to the
timed-out.js
:got/source/core/index.ts
Line 2190 in 8b88be2
And handled depending on what keys
options.timeout
has:got/source/core/utils/timed-out.ts
Lines 98 to 102 in 8b88be2
I don't yet understand why, but the internal
options
object ofgot
is passed to theClientRequest
constructor at some point of time. I can see that becauseoptions
object of our internal request interception library changes itsoptions.timeout
value fromundefined
to{}
(set bygot
) during runtime:https://github.com/mswjs/node-request-interceptor/blob/2f5a6458f41ce1b3e83eabc15a59778579d8155d/src/interceptors/ClientRequest/ClientRequestOverride.ts#L35
When
ClientRequest
is constructed with{ timeout: {} }
option that causes a type error:That behavior is according to NodeJS spec, as
options.timeout
must be a number:Expected behavior
I haven't dug that deep into
got
, but I suspect that it uses the internaloptions
object to construct aClientRequest
instance. If that's the case, I think theoptions.timeout
property should be renamed to represent the internal timeouts map, and not theClientRequest
'stimeout
options per specification.I'd be thankful for your assistance on this.
Code to reproduce
yarn install
node src/index.js
Checklist
The text was updated successfully, but these errors were encountered: