mswjs / msw

Industry standard API mocking for JavaScript.
https://mswjs.io
MIT License
16.02k stars 526 forks source link

TypeError: Failed to fetch while using redux-toolkit with new msw v. 2.0.0 #1794

Closed bukanidzee closed 1 year ago

bukanidzee commented 1 year ago

Prerequisites

Environment check

Node.js version

18.18.2

Reproduction repository

https://github.com/bukanidzee/recreate-msw-typeerror

Reproduction steps

Current behavior

Test fail and in console we can see error: { status: 'FETCH_ERROR', error: 'TypeError: Failed to fetch' } I'm not sure if this is msw issue or redux-toolkit-query so I created one for redux-toolkit as well (#3818). I also created codesandbox.

Expected behavior

Expect test to run without issues

davidgarry commented 1 year ago

Hello,

I have the same issue and my setup is almost the same as the one described above by @bukanidzee.

A few more details that could help to understand what is breaking.

I hope it will help you to find the issue 🤞

mattcosta7 commented 1 year ago

Hello,

I have the same issue and my setup is almost the same as the one described above by @bukanidzee.

A few more details that could help to understand what is breaking.

  • Without the line beforeAll(() => server.listen()), the call is correctly done to the real api (this is totally normal).
  • When I add the line beforeAll(() => server.listen()), I receive the following error : FetchError: request to xxxxx failed, reason: Cannot read properties of null (reading 'setMaxListeners')

I hope it will help you to find the issue 🤞

Cannot read properties of null (reading 'setMaxListeners')

this should be fixed in 2.0.2 via https://github.com/mswjs/msw/pull/1813 Not sure if this was the case the original issue had, but if so I expect that is fixed in the new version as well

kettanaito commented 1 year ago

The setMaxListeners issue has been fixed.

Even in 2.0.4 the reproduction repository fails. The reason for that is the relative request URL that ends up being constructed by RTK Query. I believe that is also the reason you are getting the TypeError: Failed to fetch forwarded from RTK Query.

The first thing that struck me odd is if I log anything in the matching handler http.post('/api/login', resolver), nothing gets printed. This means the handler doesn't match. But how can that be?

I then added a permissive http.all() handler which will match absolutely all outgoing traffic in the test:

http.post('*', () => {
  console.log('If this is not printed, request did not actually happen')
}),

This wasn't printed. This indicates that the FETCH_ERROR you are getting indicates a rejected request—the one that didn't even occur.

I suspect that the reason for that rejection is you constructing a relative endpoint URL while running your tests in Node.js. That's a no-op. No relative URLs in Node.js—nothing to be relative to. See https://github.com/reduxjs/redux-toolkit/issues/3284 for more details.

Once you configure your baseUrl to be absolute, the handlers are matched correctly and the resolver sends whichever response you defined:

baseQuery: fetchBaseQuery({
-  baseUrl: '/api',
+  baseUrl: new URL('/api', location.origin).href,
}),

The test still fails but I suspect something is off with the implementation, for both data and error remain undefined. I can confirm the handler matches, so it sends the response. You can look into it further to see if there are any issues with your fetching logic.

jimbolla-th commented 11 months ago

We were also running into the Cannot read properties of null (reading 'setMaxListeners') error when upgrading to MSW 2. The culprit for us was the cross-fetch polyfill in our test setup that we still had for running on older versions of Node. Removing cross-fetch eliminated the problem.

israrkhan002n commented 11 months ago

In my case the handler is getting called but still i am getting the above issue this is the response i am getting { requestId: '1xingaItFOOG99Y7v8wnO', status: 'rejected', endpointName: 'addBanner', startedTimeStamp: 1703598624590, error: { status: 'FETCH_ERROR', error: 'TypeError: Failed to fetch' }, isUninitialized: false, isLoading: false, isSuccess: false, isError: true, originalArgs: FormData {}, reset: [Function (anonymous)] }