mswjs / interceptors Goto Github PK
View Code? Open in Web Editor NEWLow-level network interception library.
Home Page: https://npm.im/@mswjs/interceptors
License: MIT License
Low-level network interception library.
Home Page: https://npm.im/@mswjs/interceptors
License: MIT License
Pre-requisite for mswjs/msw#257 and mswjs/msw#253
If a request middleware throws an exception that exits the running process (as unhandled exception).
If a request middleware throws an exception that exception should be handled, and the respective request should be cancelled (similar to a network error).
Current type annotation is invalid, as Partial<MockedResponse>
implies any of the mocked response properties could be missing. That is not true, as the library ensures all the mocked response properties are set (the values can still be undefined for properties like headers
or body
, but not for status
or statusText
).
I want to use the require method to load this module. I want to use this module in electronic. What can I do.
chunk
here is normally(?) a Buffer
, and +=
is silently calling .toString(encoding='utf-8')
on it, which is lossy. This prevents the interception of transfer encoded bodies, as this corrupts gzip
data.
Discovered in mswjs/msw#275
.end()
method does not accept arguments like chunk
/encoding
according to the NodeJS specification.
Because of this, request issuing libraries that post a request body via req.end(body)
are failing when it comes to performing an original request (request body is never written, as req.write()
is never called).
.end()
behaves according to the aforementioned specification, meaning:
chunk
argument. Appends that chunk to the existing request body.encoding
argument. Propagates that encoding to the original req.end()
call.Jest 27 removes setImmediate
, which is used in createClientRequestOverride.
Currently, I get the following in my tests:
ReferenceError: setImmediate is not defined
at ClientRequestOverride.write (~/node_modules/@mswjs/interceptors/src/interceptors/ClientRequest/createClientRequestOverride.ts:124:7)
at writeToStream (~/node_modules/node-fetch/lib/index.js:653:8)
at ~/node_modules/node-fetch/lib/index.js:1627:3
The following patch of the ClientRequest
class doesn't seem to get restored anywhere:
Restore the http.ClientRequest
to the pureClientRequest
(stored original class) in the cleanup function of interceptClientRequest
:
interceptors/src/interceptors/ClientRequest/index.ts
Lines 113 to 122 in 16fd356
Hey y'all ๐
First of all thanks for all the hard work on this library, it's nice to see this focused, low-level approach to intercepting requests.
I think there is one feature that is currently doesn't seem to be possible to achieve with this interceptor and I'm wondering if you would be interested in looking into solving this use-case.
I was about to use this lib to monitor outgoing requests of a node.js service, and what do you know there is even an example of this in the readme:
interceptor.use((req) => {
// Will print to stdout any outgoing requests
// without affecting their responses
console.log('%s %s', req.method, req.url.href)
})
One issue here though, it would be valuable to also be able to monitor response statusCode
on response end, but there is no way to hook up to original response: req
is not a real request instance, it's just normalized request options, so there is no way to attach 'response' event listener, and the second argument ref
is the mocked response instance, not the original one (which makes sense, but doesn't help with the issue too).
Effectively if you don't want to use normalized req
to send it yourself (and it's currently missing a bunch of http.request
options to do it safely) there is no way (as far as I see) to intercept incoming response. If not for monitoring, I can imagine this being useful for e.g., recording and replaying functionality, where you would actually want to conditionally either bypass the interceptor if there are no recordings or respond immediately with with a record if it exists.
One idea of the top of my head is to pass the instance of the ClientRequest to the middleware handler:
export type RequestMiddleware = (
req: InterceptedRequest,
ref: IncomingMessage | XMLHttpRequest,
req: http.ClientRequest,
) => ReturnedResponse | Promise<ReturnedResponse>
This would allow end users of the library to subscribe to response
event that will allow them to access original response info.
I'm happy to implement it, but wanted to check first if it's something that aligns with your vision of this library and get your thoughts on the subject.
- @jest-enviroment
+ @jest-environment
That way it's possible to narrow debugging per specific request. Useful when debugging parallel requests.
req.url
and the timestamp. Do this as soon as the all the prerequisites are known, so debugging is consistent and tight to the request ID through the library's execution.debug()
instance and use it everywhere.When using a supertest
library there's the following exception:
TypeError: Cannot read property 'apply' of undefined
at callSocketMethod (_http_client.js:708:27)
at onSocket (_http_client.js:716:7)
at ClientRequestOverride._deferToConnect (_http_client.js:725:5)
at ClientRequestOverride.setNoDelay (_http_client.js:758:8)
at Test.Request.request (/Users/kettanaito/Projects/contrib/msw-supertest/node_modules/superagent/lib/node/index.js:628:7)
at Test.Request.end (/Users/kettanaito/Projects/contrib/msw-supertest/node_modules/superagent/lib/node/index.js:767:8)
at Test.end (/Users/kettanaito/Projects/contrib/msw-supertest/node_modules/supertest/lib/test.js:125:7)
at Object.<anonymous> (/Users/kettanaito/Projects/contrib/msw-supertest/index.js:29:4)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
The supertest
has its own request abstraction, one of the steps of which calls req.socket.setNoDelay()
method on the Socket
instance of the request. The setNoDelay()
method is not polyfilled by NRI, which causes an exception.
Node's
_http_client.js
may call arbitrarySocket
methods during socket's lifecycle.
This error seems to be coming from node-request-interceptor while I'm running my tests with msw
(node:183) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'URL' of null
at new XMLHttpRequest (/app/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:113:42)
at /app/node_modules/node-request-interceptor/lib/XMLHttpRequest/XMLHttpRequest/createXMLHttpRequestOverride.js:211:45
That line is marked by HERE below:
module.exports = function createXMLHttpRequest(window) {
class XMLHttpRequest extends XMLHttpRequestEventTarget.interface {
constructor() { // eslint-disable-line constructor-super
const theThis = Object.create(new.target.prototype);
XMLHttpRequestEventTarget.setup(theThis);
theThis.upload = XMLHttpRequestUpload.create();
theThis.upload._ownerDocument = window.document;
theThis[xhrSymbols.flag] = {
synchronous: false,
withCredentials: false,
mimeType: null,
auth: null,
method: undefined,
responseType: "",
requestHeaders: {},
referrer: theThis._ownerDocument.URL, // <----------------- HERE
uri: "",
timeout: 0,
body: undefined,
formData: false,
preflight: false,
requestManager: theThis._ownerDocument._requestManager,
strictSSL: window._resourceLoader._strictSSL,
proxy: window._resourceLoader._proxy,
cookieJar: theThis._ownerDocument._cookieJar,
encoding: theThis._ownerDocument._encoding,
origin: theThis._ownerDocument.origin,
userAgent: window.navigator.userAgent
};
Is there something I should do differently to avoid this?
Hi all! I just have enough time to log the issue: this is something introduced by #75 ; Buffer
is one of those global vars that don't exists in RN. This is not a critical issue, as even on the user's side a simple global.Buffer = bufferPolyfill
will do to fix the issue. Another alternative is to relay on https://www.npmjs.com/package/buffer directly from this package
Hey, so working getting a mock backend of sorts setup. Currently, I'm using Got and node-request-interceptor, all on the latest versions. The first issue I'm running into here is not being able to find the withDefaultInterceptors
module in node-request-interceptor/presets/default
, I get the error Cannot find module 'node-request-interceptor/presets/default' or its corresponding type declarations.
. However, if I change the path to node-request-interceptor/lib/presets/default
, no more errors are thrown and it finds the module. Maybe I'm doing something wrong here, not sure. Here's the the mock backend -
import { RequestInterceptor } from 'node-request-interceptor';
// import withDefaultInterceptors from 'node-request-interceptor/lib/presets/default'; // this bad
import withDefaultInterceptors from 'node-request-interceptor/lib/presets/default'; // this good
import { apiUrl } from '../config.json';
export default class MockBackend {
public logger;
public interceptor;
constructor(logger) {
this.logger = logger;
this.interceptor = new RequestInterceptor(withDefaultInterceptors);
}
intercept() {
this.interceptor.use((req) => {
if ([apiUrl].includes(req.url.origin)) {
return {
status: 301,
headers: {
'x-powered-by': 'node-request-interceptor',
},
body: JSON.stringify({
message: 'Hey, I am a mocked response',
}),
}
}
})
}
}
Anywho, next issue, whenever I'm using Got, it throws an error,
(node:8924) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_ARG_TYPE]: The "timeout" argument must be of type number. Received an instance of Object
at validateNumber (internal/validators.js:122:11)
at getTimerDuration (internal/timers.js:376:3)
at new ClientRequest (_http_client.js:167:20)
at request (https.js:314:10)
at Object.proxiedOriginalRequest (C:\Users\Lyon\Documents\GitHub\squadops-discordbot-v5\node_modules\node-request-interceptor\lib\interceptors\ClientRequest\index.js:54:36)
at ClientRequestOverride.<anonymous> (C:\Users\Lyon\Documents\GitHub\squadops-discordbot-v5\node_modules\node-request-interceptor\lib\interceptors\ClientRequest\ClientRequestOverride.js:235:39)
at step (C:\Users\Lyon\Documents\GitHub\squadops-discordbot-v5\node_modules\node-request-interceptor\lib\interceptors\ClientRequest\ClientRequestOverride.js:33:23)
at Object.next (C:\Users\Lyon\Documents\GitHub\squadops-discordbot-v5\node_modules\node-request-interceptor\lib\interceptors\ClientRequest\ClientRequestOverride.js:14:53)
at fulfilled (C:\Users\Lyon\Documents\GitHub\squadops-discordbot-v5\node_modules\node-request-interceptor\lib\interceptors\ClientRequest\ClientRequestOverride.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(node:8924) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhan
dled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
I have no idea why it does this, clearly. Here is the file relating that calls this -
import { apiUrl } from '../config.json';
import got from 'got';
export default class OpsService {
public logger;
public path = apiUrl;
constructor(logger: any) {
this.logger = logger;
}
async getSession(sess_id) {
const requestPath = `${this.path}/sessions/${sess_id}`;
this.logger.warn('Ops Service',`Executing call to ${requestPath}`);
const body = await got.get(requestPath);
console.log(body);
}
}
requestPath
is valid, otherwise Got would have thrown an error. Kind of clueless here as to why it throws this error. Any help would be much appreciated.
Please help me with how to use this library with jest for testing without making network requests.
setImmediate
is not defined (#123)TypeError [ERR_INVALID_ARG_TYPE]: The "options.agent" property must be one of Agent-like Object, undefined, or false. Received an instance of Object
ReferenceError: browserType.launch: setImmediate is not defined
when running in-browser tests.See the workaround test:
The order of the XMLHttpRequest events must be this:
['loadstart', 1],
['readystatechange', 2],
['readystatechange', 4],
['load', 4],
['loadend', 4],
There must be no duplicate ['readystatechange', 4]
event.
XMLHttpRequest polyfill from JSDOM executes the attached readystatechange
listeners as a part of XMLHttpRequest life-cycle, which is correct. However, somehow the way that the listener is attached makes it being called twice.
I've got code that looks like this:
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener("progress", (e) => {
// ...
})
When I run my test I get this error:
TypeError: Cannot read property 'addEventListener' of null
40 | const xhr = new XMLHttpRequest()
41 | console.log(xhr)
> 42 | xhr.upload.addEventListener("progress", (e) => {
That console.log reveals that the upload property of the class is set to null.
XMLHttpRequestOverride {
upload: null
}
If someone points me in the right direction, I'd be open to filling in this gap.
socket.io timeout
In my Jest test:
import {setupServer} from 'msw/node';
console.log(XMLHttpRequest.DONE);
// logs: 4
setupServer();
console.log(XMLHttpRequest.DONE);
// logs: undefined
I am using:
Discovered in mswjs/msw#203
XMLHttpRequest module override relies on re-creating a ProgressEvent
in case of hooking into XHR progress callbacks.
ProgressEvent
constructor does not exist in React Native environment.
A request in the style of require('https').request({host: 'www.banana.com', path: '/cherry'})
should be normalised to an https request, not http. I have created a pull request with a failing test and more information, so that the discussion may be continue there.
Hello,
I'm using https://github.com/sindresorhus/got to make requests from node but looks like it doesn't work with node-request-interceptor.
I get this errror :
Any advices? Thanks in advance
i have the following code in my project:
const interceptor = new (createInterceptor as any)({
modules: nodeInterceptors,
});
interceptor.apply();
interceptor.on('request', (request: IsomorphicRequest) => {
this.logger.log(
'=============request============\n\n%s\n\n========================',
JSON.stringify(request)
);
});
interceptor.on(
'response',
(req: IsomorphicRequest, res: IsomorphicResponse) => {
this.logger.log(
'=============request============\n\n%s\n=============response============\n\n%s\n\n========================',
JSON.stringify(req),
JSON.stringify(res)
);
}
);
process.on('disconnect', () => {
interceptor.restore();
});
the listener on request
works fine, and logs every request. But, the listener on response
is never logging anything. am i missing any setup/config?
Request with the x-msw-bypass
header is matched against the request middleware. This means that the bypass header does not affect the mocking behavior as it should.
Whenever encountered a request with the x-msw-bypass
header, there must be no matching against the request middleware. Such request should be performed as-is, regardless if there's a middleware that can handle it.
To preserve the same behavior present in the ctx.fetch()
in MSW.
TypeError [ERR_INVALID_PROTOCOL]: Protocol "http:" not supported. Expected "https:"
at Object.proxiedOriginalRequest (node_modules/node-request-interceptor/lib/http/override.js:55:36)
at ClientRequestOverride.<anonymous> (node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js:244:39)
at step (node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js:33:23)
at Object.next (node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js:14:53)
at fulfilled (node_modules/node-request-interceptor/lib/http/ClientRequest/ClientRequestOverride.js:5:58)
This happens when mock https request.
This error occurs because there is no cert
property in options
.
so options.protocol
always set as http:
console.log(options); // No 'cert' property in `options` object.
// Assume HTTPS if using an SSL certificate.
options.protocol = options.cert ? 'https:' : DEFAULT_PROTOCOL
console.log(options)
result
fetch('https://...')
=> log: https-log.txtfetch('http://...')
=> log: http-log.txtI think, options.protocol
value should be decided by options.uri.protocol === 'https:'
https://github.com/gwanduke/example-node-request-interceptor-issue-45
App.js
...
fetch('https://example.com')
...
App.test.js
setupServer(
rest.get('https://example.com', (req, res, ctx) => {
return res(
ctx.json({})
);
})
);
test('render', async () => {
render(<App />);
});
fetch('/login')
request in Node-like environment.XMLHttpRequest
class: TypeError: Invalid URL: /login
2152 | this.readyState = this.LOADING;
2153 | this.data = data || '';
> 2154 | const url = new URL(this.url);
| ^
2155 | const req = {
2156 | url: cleanUrl(url),
2157 | method: this.method,
Hi all! I've had an issue testing an auth integration with MSW and traced it to case sensitivity in the getResponseHeader
function when retrieving the header value. I've created a PR with more detail here: #89
It looks like the current implementation was intentional so I'm keen to hear more if my PR is a breaking change for anyone? Either way I hope there's some way around this!
When attaching a debugger to the following code (with breakpoints set at the request and response interceptors):
export class NodeHttpClient implements Provider<AxiosLike> {
value() {
const interceptor = createInterceptor({
modules: nodeInterceptors,
resolver(request) {},
});
interceptor.on('request', (request) => {
console.log(request);
return request;
});
interceptor.on('response', (request, response) => {
console.log(request, response);
return response;
});
const instance = axios.create();
instance.defaults.adapter = require('axios/lib/adapters/http');
interceptor.apply();
return instance;
}
}
it appears as if the request interceptor is skipped and execution is started with the response interceptor when a request is initiated. I've tried this with other interceptor modules and they all behave the same way.
I'd appreciate any help looking into this or a direction to be pointed towards to resolve this, especially if it's something minor I'm overlooking.
Thank you!
Sorry about this, just an heads up on #37
This, while it correctly allow me to run msw on the application, it broke my tests. Apparently, while running my jest tests, the overrideModules.native.ts
is also loaded, which is not the behaviour I was expecting.
I'll look more into this tonight.
I'd been using axios just fine to basically build a much simpler nock
-type interface using node-request-interceptor
(fantastic lib btw! thanks for providing it), but then i realized that in my real tests, which will be consuming the interface i'm making, i'm using
axios.defaults.adapter = require('axios/lib/adapters/http');
.so once i remembered and i set that adapter line (2^), my code, which was working beautifully, started throwing:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type object
Here's a repro file, which throws unless you assign a string to body:
or if you comment out the axios.defaults.adapter
line.
'use strict';
const { RequestInterceptor } = require('node-request-interceptor');
const withDefaultInterceptors = require('node-request-interceptor/lib/presets/default').default;
const interceptor = new RequestInterceptor(withDefaultInterceptors);
function handleResponse(request) {
return {
status: 200,
headers: {
some: 'header'
},
body: {
valueFromObject: 'thisWorkedWithTheOtherAxiosAdapter'
}
};
}
interceptor.use(handleResponse);
const axios = require('axios');
axios.defaults.adapter = require('axios/lib/adapters/http');
describe('Repo my test that is breaking', () => {
it('Returns the expecting string error', async () => {
const iWontGetHere = await axios('http://theurlshouldntmatter.com');
console.log(iWontGetHere);
});
});
Thank you in advance! I tried JSON.stringify()
ing the object, but then it escapes the JSON characters and iWontGetHere.data
becomes a string rather than the object i would be expecting
When intercepting an XMLHttpRequest
instance, NRI doesn't respect its timeout
option. This causes tools that utilize timeout to fail, as performing such requests originally omits the previously assigned timeout.
EXTERNAL_TOOL (timeout) -> NRI -> captured, perform original -> original (NO timeout)
XMLHttpRequest
instances inherit and propagate the timeout
property. This only affects XHR issues in async
mode.
Hello
I use mock-service-worker for writing tests in my application and I faced a problem. My application use rxjs/ajax for making network request and rxjs/ajax expects xhrRequest.response to be a javascript object, when xhrRequest.responseType equals "json"(this behavior is described here https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response), but mock-service-worker, that using node-request-interceptor, returns xhrRequest.response type of string.
This behavior makes my application work differently in tests and in the browser. Is this behavior a bug in node-request-interceptor?
I am using Axios to get the raw stream, but Interceptors read the stream in utils/getIncomingMessageBody
, so that the downstream http client cannot read the stream anymore. This can be a side effect and ideally that stream should be piped and not touch the original stream.
When using msw on node for requests created by got I'll get the following error.
at validateNumber (internal/validators.js:129:11)
at getTimerDuration (internal/timers.js:381:3)
at new ClientRequest (_http_client.js:170:20)
at request (http.js:50:10)
at Object.proxiedOriginalRequest (./node_modules/node-request-interceptor/src/interceptors/ClientRequest/index.ts:67:29)
at ClientRequestOverride.<anonymous> (./node_modules/node-request-interceptor/src/interceptors/ClientRequest/ClientRequestOverride.ts:268:15)
at step (./node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:33:23)
at Object.next (./node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:14:53)
at fulfilled (./node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
The initial requested created by me doesn't even contain a timeout value.
I've created a minimal repo to showcase the error: https://github.com/KnisterPeter/node-request-interceptor-with-got-issue
Current implementation proxies options.headers
to the intercepted request instance:
Different request issuing libraries format headers differently. For instance:
node-fetch
capitalizes all headers names;whatwg-fetch
converts header names to start with lowercase.This difference makes it problematic to properly asserts an intercepted request headers in tests.
Headers names must be formatted to start with lowercase.
Current build setup produces JavaScript artifacts that are hard to debug (compile code is not readable).
The build process should be minimal (stripping off type declarations). Code transformation shouldn't be needed, as the target version of node (>=10
) should support all the features used in the library's source code.
http.request('http://httpbin.org/get')
http.request('http://httpbin.org/get', { headers: { 'foo': 'bar' } })
When accessed in the middleware function, the second request will not have the headers
present, as the first request interferes with it.
Each of the hosts must be processed separately.
node-request-interceptor/interceptors/[name]
SocketPolyfill
).When cloning an object like this:
cloneObject({
key: Object.create(null)
})
The internal cloneObject
function throws the following exception:
TypeError: Cannot read property 'name' of undefined
Objects with null prototype don't have a constructor. The cloneObject
function must check the constructor's existence before accessing it.
Hello,
I'm trying to intercept all network requests on a web app. I'd like to record everything that shows up in the Networks tab in the browser developer tools (except for web sockets).
I've added interceptors
to my web app:
const interceptor = createInterceptor({
modules: browserInterceptors,
resolver(req, ref) {
console.log(req.url);
console.log(ref);
},
});
interceptor.apply();
I have 2 buttons that make requests:
<button
onClick={async () => {
const data = await fetch(
'https://pokeapi.co/api/v2/pokemon/1'
);
const json = await data.json();
console.info({ json });
}}
>
Fetch Request
</button>
<button
onClick={async () => {
const oReq = new XMLHttpRequest();
oReq.open('GET', 'https://pokeapi.co/api/v2/pokemon/1');
oReq.send();
}}
>
XHR
</button>
fetch
isn't. I'm getting this error for fetch
: TypeError: Failed to execute 'json' on 'Response': body stream already read
browserInteceptors
module, fetch
and XMLHttpRequest
are being shimmed. I checked this by running fetch
and XMLHttpRequest
in the console and the output was not XMLHttpRequest() { [native code] }
.Given an HTTPS request constructed like this:
https.request(new URL('...'), { ... })
The request's URL is never set on the original call to https.request
:
interceptors/src/interceptors/ClientRequest/createClientRequestOverride.ts
Lines 276 to 277 in 175bb79
The normalized options
in this case contain the url
property, which is an unknown property for the function call.
The presence of the unexpected "url" property may be related to how the request options are constructed in the used library (
@auth0/nextjs-auth0
). This library does not append the "url" property on the request options.
The original HTTPS request is performed properly, its request's URL is preserved.
This can be achieved the same way the original HTTP requests are handled:
By providing the first explicit option (stringified request URL due to the incompatibility between the standard URL
class and the import('url').URL
that https
module relies on), and passing the rest of the request options as the second argument.
Some of the events are grouped together, not representing the valid flow of an XHR request:
The XMLHttpRequest
events must be dispatched in the order described in the specification to guarantee compatibility for the users.
๐ again (excited to be one of the first users of the low-level lib)
as part of my product, i'm trying to allow users to "lock" the state of their microservice, and cache the responses of any outbound requests. but during this "locking", i get in an intermediate state, where i need some requests to go through transparently (aws), but the rest to be intercepted (requests to e.g. our other services, public APIs, etc)
i have a feeling aws-sdk
is doing something sketchy here, but when i just have the interceptor enabled, here's the error i get trying to allow the aws requests to go through (I have some matching logic that returns undefined for them):
(node:74163) UnhandledPromiseRejectionWarning: TypeError [ERR_INVALID_PROTOCOL]: Protocol "http:" not supported. Expected "https:"
at new ClientRequest (_http_client.js:120:11)
at request (https.js:289:10)
at Object.proxiedOriginalRequest (/Users/scottyjacobson/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/index.js:54:36)
at ClientRequestOverride.<anonymous> (/Users/scottyjacobson/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:241:39)
at step (/Users/scottyjacobson/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:33:23)
at Object.next (/Users/scottyjacobson/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:14:53)
at fulfilled (/Users/scottyjacobson/node_modules/node-request-interceptor/lib/interceptors/ClientRequest/ClientRequestOverride.js:5:58)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
at startup (internal/bootstrap/node.js:283:19)
(node:74163) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:74163) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
reproduction steps:
'use strict'
const { RequestInterceptor } = require('node-request-interceptor')
const withDefaultInterceptors = require('node-request-interceptor/lib/presets/default')
.default
const interceptor = new RequestInterceptor(withDefaultInterceptors)
interceptor.use(() => {
return undefined
});
const AWS = require('aws-sdk');
AWS.config.update({region:'us-east-1'});
const s3 = new AWS.S3();
s3.getObject({
Bucket: 'this.bucket.dont.matter',
Key: 'neither.does.this'
}).promise();
package.json:
{
"name": "request-interceptor-59",
"version": "1.0.0",
"main": "index.js",
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.759.0",
"node-request-interceptor": "^0.5.1"
}
}
i know there's 218937423894 moving pieces in the aws-sdk, and i wish i could get you a more isolated repro case, but the inner workings of aws-sdk
's use of http
vs https
(and yours for that matter) is slightly out of my pay grade. happy to help hunt down the issue if you know what direction to go looking in!
thanks!
Scotty
When constructing a URL
instance out of RequestOptions
we need to respect options.username
and options.password
to be set in the respective properties of the URL
instance.
To propagate the authentication data to the URL instance.
getUrlByRequestOptions
utility.username
and password
properties to the created URL
instance.Hi, I am using msw with nextjs and I came across an error when working on the api route. The error log points to this library so I'm here.
here is a minimal repo: https://github.com/dpyzo0o/next-msw-bug-demo
yarn dev
, which enables msw. Then try to click download image
, the first time it will probably succeed (sometimes it also fails the first time). Then do a hard refresh of the page and click download image again. This time it will error out, the error message shown below points to node-request-interceptor
yarn build && yarn start
, which basically disables msw, it will never throw this error and everything works.I'd really appreciate it if you could help me.
We know that there is a problem when using multiple interceptors. restore
function will remove monkey patches even if there are other interceptors. The last one is mswjs/msw#637
The solution of this problem is not really easy but what you think if we add a counter on the interceptor? I know that is not a complete solution but could be a first start
--- a/src/createInterceptor.ts
+++ b/src/createInterceptor.ts
@@ -63,12 +63,15 @@ export interface InterceptorApi {
restore(): void
}
+let interceptosCounter = 0
+
export function createInterceptor(options: InterceptorOptions): InterceptorApi {
const observer = new StrictEventEmitter<InterceptorEventsMap>()
let cleanupFns: InterceptorCleanupFn[] = []
return {
apply() {
+ interceptosCounter++
cleanupFns = options.modules.map((interceptor) => {
return interceptor(observer, options.resolver)
})
@@ -78,14 +81,16 @@ export function createInterceptor(options: InterceptorOptions): InterceptorApi {
},
restore() {
observer.removeAllListeners()
-
+ interceptosCounter--
if (cleanupFns.length === 0) {
throw new Error(
`Failed to restore patched modules: no patches found. Did you forget to run ".apply()"?`
)
}
- cleanupFns.forEach((restore) => restore())
+ if (interceptosCounter === 0) {
+ cleanupFns.forEach((restore) => restore())
+ }
},
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.