Skip to content
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

Usage with MSW / patched fetch #295

Open
meesvandongen opened this issue Sep 11, 2023 · 13 comments
Open

Usage with MSW / patched fetch #295

meesvandongen opened this issue Sep 11, 2023 · 13 comments
Labels
documentation Improvements or additions to documentation

Comments

@meesvandongen
Copy link

meesvandongen commented Sep 11, 2023

Environment

Node

Reproduction

https://codesandbox.io/p/sandbox/stoic-https-6gjdtz?file=/index.js:14,16

import { setupServer } from "msw/node";
import { http, HttpResponse } from "msw";
import wretch from 'wretch'
import { ofetch, fetch, createFetch } from 'ofetch'
import got from 'got'

const server = setupServer(
    http.get('https://example.com', () => {
        return HttpResponse.text('1')
    })
)
server.listen();

console.table([
 ['fetch', await globalThis.fetch('https://example.com').then(res => res.text()).then(res => res === '1')],
 ['ofetch fetch', await fetch('https://example.com').then(res => res.text()).then(res => res === '1')],
 ['ofetch createFetch', await createFetch()('https://example.com').then(res => res === '1')],
 ['ofetch', await ofetch('https://example.com').then(res => res === '1')],
 ['wretch', await wretch('https://example.com').get().text().then(res => res === '1')],
 ['got', await got.get('https://example.com').text().then(res => res === '1')],
])

CleanShot 2023-12-23 at 14 00 06@2x

Describe the bug

When other tools patch fetch, the global instance of ofetch will have the original fetch instance. This will cause tools such as msw to not be able to intercept requests with ofetch. A workaround could be to only get the globalThis.fetch at request time if no other fetch is specified.

Additional context

Users can work around this at this time by using the createFetch helper function.

Logs

No response

@mohammadGh
Copy link

mohammadGh commented Nov 1, 2023

Thanks @meesvandongen for opening this issue, which is also a problem we have encountered. PooyaJaan @pi0 please let us know what is the best and efficient temporary solution to solve this problem until it is resolved? Should we use the createFetch function?

@pi0 pi0 added the documentation Improvements or additions to documentation label Nov 1, 2023
@edumudu
Copy link

edumudu commented Nov 17, 2023

For anyone coming here, I found a hacky but functional way to workaround this for now using the Proxy constructor

function createMyFetch() {
  const newFetch = createFetch({
    fetch: globalThis.fetch,
    Headers: globalThis.Headers,
  });

  return newFetch.create({
    // ...default options
  });
}

const original = createMyFetch();

export const http = new Proxy(original, {
  apply(_, thisArg, argumentsList) {
    return Reflect.apply(createMyFetch(), thisArg, argumentsList);
  },
});

// Then in other file calling `http` will be intercepted but maintaining the same usage
http('https://jsonplaceholder.typicode.com/todos/1')

This will work with [email protected] and [email protected]. You can merge the arguments instead of creating a new stance every time, or creating one only on the first call, etc

@rinux55
Copy link

rinux55 commented Dec 16, 2023

Running into this issue as well, a fix or workaround for usage with msw would be greatly appreciated.

@stichingsd-vitrion
Copy link

stichingsd-vitrion commented Jan 5, 2024

Running into this issue as well, a fix or workaround for usage with msw would be greatly appreciated.

Same here, not working with Nuxt in my case for MSW serverside outgoing calls
EDIT:

After more debuggin in nuxtJS i found out above issue is main issue mocking in server/api is not working (calls to third parties

export default defineEventHandler(async (event) => {
  const data = await createFetch()(
    'https://jsonplaceholder.typicode.com/todos/1',
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    },
  )
  console.log(JSON.stringify(data))
  return {
    hello: 'world',
  }
})

Right now i fixed it by using the createFetch insteda of $fetch from nuxt.

@mydea
Copy link

mydea commented Feb 15, 2024

Just adding on here, this is also apparently a problem when using Sentry in the Browser - any requests made via ofetch will not be captured by the monkey-patched fetch that Sentry relies on to capture network requests, sadly.

@dwightjack
Copy link
Contributor

I think this same problem (even if not strictly an issue with ofetch) happens with Datadog RUM: #339

@dwightjack
Copy link
Contributor

I might have found a possible, non-breaking solution to this problem and submitted a PR, but I wonder whether it is effective in all scenarios.

@mentalrob

This comment was marked as off-topic.

@cy-moi
Copy link

cy-moi commented Apr 24, 2024

Here is a possible workaround for me with useFetch hook in Nuxt.

useFetch(url, {
    $fetch: createFetch({
      fetch: globalThis.fetch,
      Headers: globalThis.Headers,
    }), 
   ...options,
  });

Maybe this could be better supported in Nuxt.

@artmizu
Copy link

artmizu commented May 13, 2024

I'm too humbly awaiting the solution, thank you, guys, for your time! Tried to overcome the issue by myself, but for now don't see any available options.

@shunnNet
Copy link

For someone who stuck in Nuxt + ofetch, I have created a Nuxt module nuxt-msw, which integrate msw with Nuxt.

@cctidal
Copy link

cctidal commented Aug 30, 2024

This issue was a deciding factor against using ofetch when migrating an app that was using request even though the ofetch api is really nice 😞

@pi0
Copy link
Member

pi0 commented Aug 30, 2024

Next version of ofetch will use patched fetch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests