Support IPv6
Maybe I'm missing something but:
const { ClientRequestInterceptor } = require('@mswjs/interceptors/ClientRequest')
const http = require('http')
const interceptor = new ClientRequestInterceptor({
name: 'my-interceptor',
})
interceptor.apply();
interceptor.on('request', ({request}) => {
request.respondWith(new Response('hey'))
});
http.get('http://[2607:f0d0:1002:51::4]:8080/', res => {
res.on('data', () => {})
res.on('end', () => {
console.log(1)
})
})
Prints:
RequestError: connect ENETUNREACH 2607:f0d0:1002:51::4:8080 - Local (:::0)
Logs:
02:24:25:826 [http] constructing the interceptor...
02:24:25:843 [http:apply] applying the interceptor...
02:24:25:843 [http] retrieved global instance: undefined
02:24:25:843 [http:apply] no running instance found, setting up a new instance...
02:24:25:844 [http:setup] native "http" module patched!
02:24:25:844 [http:setup] native "https" module patched!
02:24:25:844 [http] set global instance! http
02:24:25:844 [http:on] adding "request" event listener:
02:24:25:845 [http normalizeClientRequestArgs] arguments ["http://[2607:f0d0:1002:51::4]:8080/",null]
02:24:25:845 [http normalizeClientRequestArgs] using default protocol: http:
02:24:25:845 [http normalizeClientRequestArgs] first argument is a location string: http://[2607:f0d0:1002:51::4]:8080/
02:24:25:845 [http normalizeClientRequestArgs] created a url: "http://[2607:f0d0:1002:51::4]:8080/"
02:24:25:846 [http normalizeClientRequestArgs] request options from url: {"method":"GET","protocol":"http:","hostname":"2607:f0d0:1002:51::4","host":"[2607:f0d0:1002:51::4]:8080","path":"/","port":8080}
02:24:25:846 [http normalizeClientRequestArgs] request options not provided, deriving from the url "http://[2607:f0d0:1002:51::4]:8080/"
02:24:25:846 [http normalizeClientRequestArgs] resolved request options: {"method":"GET","protocol":"http:","hostname":"2607:f0d0:1002:51::4","host":"[2607:f0d0:1002:51::4]:8080","path":"/","port":8080}
02:24:25:847 [http normalizeClientRequestArgs] resolved fallback agent: {"_events":{},"_eventsCount":2,"defaultPort":80,"protocol":"http:","options":{"noDelay":true,"path":null},"requests":{},"sockets":{},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":false,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":0}
02:24:25:847 [http normalizeClientRequestArgs] has no default agent, setting the default agent for "http:"
02:24:25:847 [http normalizeClientRequestArgs] successfully resolved url: http://[2607:f0d0:1002:51::4]:8080/
02:24:25:847 [http normalizeClientRequestArgs] successfully resolved options: {"method":"GET","protocol":"http:","hostname":"2607:f0d0:1002:51::4","host":"[2607:f0d0:1002:51::4]:8080","path":"/","port":8080,"agent":{"_events":{},"_eventsCount":2,"defaultPort":80,"protocol":"http:","options":{"noDelay":true,"path":null},"requests":{},"sockets":{},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":false,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":0},"_defaultAgent":{"_events":{},"_eventsCount":2,"defaultPort":80,"protocol":"http:","options":{"keepAlive":true,"scheduling":"lifo","timeout":5000,"noDelay":true,"path":null},"requests":{},"sockets":{},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":true,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":0}}
02:24:25:847 [http normalizeClientRequestArgs] successfully resolved callback: res => {
res.on('data', () => {})
res.on('end', () => {
console.log(1)
})
}
02:24:25:851 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] constructing ClientRequest using options: {"url":"http://[2607:f0d0:1002:51::4]:8080/","requestOptions":{"method":"GET","protocol":"http:","hostname":"2607:f0d0:1002:51::4","host":"[2607:f0d0:1002:51::4]:8080","path":"/","port":8080,"agent":{"_events":{},"_eventsCount":2,"defaultPort":80,"protocol":"http:","options":{"noDelay":true,"path":null},"requests":{},"sockets":{"2607:f0d0:1002:51::4:8080:":[{"connecting":true,"_hadError":false,"_parent":null,"_host":null,"_closeAfterHandlingError":false,"_readableState":{"objectMode":false,"highWaterMark":16384,"buffer":{"head":null,"tail":null,"length":0},"length":0,"pipes":[],"flowing":null,"ended":false,"endEmitted":false,"reading":false,"constructed":true,"sync":true,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"errorEmitted":false,"emitClose":false,"autoDestroy":true,"destroyed":false,"errored":null,"closed":false,"closeEmitted":false,"defaultEncoding":"utf8","awaitDrainWriters":null,"multiAwaitDrain":false,"readingMore":false,"dataEmitted":false,"decoder":null,"encoding":null},"_events":{},"_eventsCount":6,"_writableState":{"objectMode":false,"highWaterMark":16384,"finalCalled":false,"needDrain":false,"ending":false,"ended":false,"finished":false,"destroyed":false,"decodeStrings":false,"defaultEncoding":"utf8","length":0,"writing":false,"corked":0,"sync":true,"bufferProcessing":false,"writecb":null,"writelen":0,"afterWriteTickInfo":null,"buffered":[],"bufferedIndex":0,"allBuffers":true,"allNoop":true,"pendingcb":0,"constructed":true,"prefinished":false,"errorEmitted":false,"emitClose":false,"autoDestroy":true,"errored":null,"closed":false,"closeEmitted":false},"allowHalfOpen":false,"_sockname":null,"_pendingData":null,"_pendingEncoding":"","server":null,"_server":null}]},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":false,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":1},"_defaultAgent":{"_events":{},"_eventsCount":2,"defaultPort":80,"protocol":"http:","options":{"keepAlive":true,"scheduling":"lifo","timeout":5000,"noDelay":true,"path":null},"requests":{},"sockets":{},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":true,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":0}}}
02:24:25:852 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] end []
02:24:25:852 [utils getUrlByRequestOptions] arguments []
02:24:25:853 [utils getUrlByRequestOptions] normalized args [null,null,null]
02:24:25:853 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] normalized arguments: {"chunk":null,"encoding":null,"callback":null}
02:24:25:867 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] emitting the "request" event for 2 listener(s)...
02:24:25:871 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] emit: socket
02:24:25:871 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] emit: error
02:24:25:871 [http:request GET http://[2607:f0d0:1002:51::4]:8080/] error:
{"errno":-101,"code":"ENETUNREACH","syscall":"connect","address":"2607:f0d0:1002:51::4","port":8080}
node:events:492
throw er; // Unhandled 'error' event
^
Error: connect ENETUNREACH 2607:f0d0:1002:51::4:8080 - Local (:::0)
at internalConnect (node:net:1090:16)
at defaultTriggerAsyncIdScope (node:internal/async_hooks:464:18)
at node:net:1315:9
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
Emitted 'error' event on _NodeClientRequest instance at:
at _NodeClientRequest.emit (/.../nock/node_modules/@mswjs/interceptors/lib/node/chunk-44QGFZIT.js:353:18)
at Socket.socketErrorListener (node:_http_client:495:9)
at Socket.emit (node:events:514:28)
at emitErrorNT (node:internal/streams/destroy:151:8)
at emitErrorCloseNT (node:internal/streams/destroy:116:3)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
errno: -101,
code: 'ENETUNREACH',
syscall: 'connect',
address: '2607:f0d0:1002:51::4',
port: 8080
}
Node.js v20.6.1
Can you please give it a quick try by adding the error code (ENETUNREACH) to the list of suppressed error codes here:
https://github.com/mswjs/interceptors/blob/2e98a714bc4364fb201313c1bcd326b3b2767a61/src/interceptors/ClientRequest/NodeClientRequest.ts#L35
I think that may solve the issue. We keep an internal list of socket errors to ignore to know that those are expecting, such as when trying to connect to an address that doesn't exist.
Yes. It does solve it. Thanks! I focus on fixing nocks tests, so I'll open a PR later.
Released: v0.25.7 🎉
This has been released in v0.25.7!
Make sure to always update to the latest version (npm i @mswjs/interceptors@latest) to get the newest features and bug fixes.
Predictable release automation by @ossjs/release.
@kettanaito Eventually we didn't fix this in https://github.com/mswjs/interceptors/pull/454. Can you please reopen this?
@mikicho, thanks for letting me know. Apologies, I've been busy with the MSW 2.0 release and everything around so I fell off our effort here. It is still something I want to achieve so please ping me anywhere I can help.
Released: v0.29.0 🎉
This has been released in v0.29.0!
Make sure to always update to the latest version (npm i @mswjs/interceptors@latest) to get the newest features and bug fixes.
Predictable release automation by @ossjs/release.