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

TypeError: Failed to fetch in a miniflare-like environment #1834

Closed
4 tasks done
monoald opened this issue Nov 4, 2023 · 16 comments · Fixed by #1845
Closed
4 tasks done

TypeError: Failed to fetch in a miniflare-like environment #1834

monoald opened this issue Nov 4, 2023 · 16 comments · Fixed by #1845
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node

Comments

@monoald
Copy link

monoald commented Nov 4, 2023

Prerequisites

Environment check

  • I'm using the latest msw version
  • I'm using Node.js version 18 or higher

Node.js version

v20.1.0

Reproduction repository

https://github.com/monoald/auth-hono

Reproduction steps

  • npm i
  • npm test

Current behavior

console.error
    Trace: TypeError: Failed to fetch
        at createNetworkError (/home/monoald/project/packages/hono-auth/node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.js:140:24)
        at globalThis.fetch (/home/monoald/project/packages/hono-auth/node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.js:80:31)
        at AuthFlow.getTokenFromCode (/home/monoald/project/packages/hono-auth/src/service/google/authFlow.ts:102:22)
        at AuthFlow.getUserData (/home/monoald/project/packages/hono-auth/src/service/google/authFlow.ts:136:40)
        at /home/monoald/project/packages/hono-auth/src/service/google/googleAuth.ts:48:5
        at /home/monoald/project/packages/hono-auth/node_modules/hono/dist/cjs/hono-base.js:260:62 {
      cause: TypeError: unusable
          at Request.clone (/home/monoald/project/packages/hono-auth/node_modules/@miniflare/core/node_modules/undici/lib/fetch/request.js:688:13)
          at Request.clone (/home/monoald/project/packages/hono-auth/node_modules/@miniflare/core/src/standards/http.ts:478:38)
          at HttpHandler.<anonymous> (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/handlers/RequestHandler.js:112:43)
          at Generator.next (<anonymous>)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/handlers/RequestHandler.js:53:61
          at new Promise (<anonymous>)
          at __async (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/handlers/RequestHandler.js:37:10)
          at HttpHandler.run (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/handlers/RequestHandler.js:107:12)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/getResponse.js:48:28
          at Generator.next (<anonymous>)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/getResponse.js:36:61
          at new Promise (<anonymous>)
          at __async (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/getResponse.js:20:10)
          at getResponse (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/getResponse.js:44:63)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/handleRequest.js:58:49
          at until (/home/monoald/project/packages/hono-auth/node_modules/@open-draft/until/src/until.ts:23:24)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/handleRequest.js:57:55
          at Generator.next (<anonymous>)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/handleRequest.js:36:61
          at new Promise (<anonymous>)
          at __async (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/handleRequest.js:20:10)
          at handleRequest (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/core/utils/handleRequest.js:49:10)
          at SetupServerApi.<anonymous> (/home/monoald/project/packages/hono-auth/node_modules/msw/lib/node/index.js:93:69)
          at Generator.next (<anonymous>)
          at /home/monoald/project/packages/hono-auth/node_modules/msw/lib/node/index.js:36:61
          at new Promise (<anonymous>)
          ...
          ...

Trying to test using Hono JS, I followed all the necessary setup for jest, but still get the error.

Expected behavior

The test should run without any error and mock fetch request.

@monoald monoald added bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node labels Nov 4, 2023
@Ruddickmg
Copy link

I have this same issue

@mattcosta7
Copy link
Contributor

@monoald I think there's something here:

1 - the error you're seeing is from your attempt to log request.json, I think you want to await request.clone().json() to copy that rquest properly before reading it, since a body can only be read once

Once doing that, we do get a different error

Trace: TypeError: Failed to fetch
        at createNetworkError (/workspaces/auth-hono/node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.js:140:24)
        at globalThis.fetch (/workspaces/auth-hono/node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.js:80:31)
        at AuthFlow.getTokenFromCode (/workspaces/auth-hono/src/service/google/authFlow.ts:102:22)
        at AuthFlow.getUserData (/workspaces/auth-hono/src/service/google/authFlow.ts:136:40)
        at /workspaces/auth-hono/src/service/google/googleAuth.ts:48:5
        at /workspaces/auth-hono/node_modules/hono/dist/cjs/hono-base.js:259:62 {
      cause: Error: Failed to get the 'credentials' property on 'Request': the property is not implemented.
          at unimplemented (/workspaces/auth-hono/node_modules/@miniflare/core/src/standards/http.ts:96:9)
          at Request.get credentials [as credentials] (/workspaces/auth-hono/node_modules/@miniflare/core/src/standards/http.ts:520:12)
          at CookieStore.get (/workspaces/auth-hono/node_modules/@mswjs/cookies/src/store.ts:92:21)
          at getAllRequestCookies (/workspaces/auth-hono/node_modules/msw/lib/core/utils/request/getRequestCookies.js:76:66)
          at HttpHandler.<anonymous> (/workspaces/auth-hono/node_modules/msw/lib/core/handlers/HttpHandler.js:106:73)

Which looks like an issue with the way Request is implemented in miniflare/cloudflare workers?

We may need to wrap reads of credentials to help support that environment

@mattcosta7
Copy link
Contributor

mattcosta7 commented Nov 6, 2023

It looks like there are a few places we read properties unavailable in cloudflares Request/Response objects.

here are the lines I modified (in node_modules directly to get things cleared up)

first, the log lines: (this, being non-synchronous) will likely end after your test does and cause some warnings.

- server.events.on("request:start", ({ request }) => {
+ server.events.on("request:start", async ({ request }) => {
  console.log(
    "MSW intercepted:",
    request.method,
    request.url,
-     request.json()
+    await request.clone().json()
  );
});

request.credentials:

response.type - https://github.com/mswjs/interceptors/blob/3258f5cc62c472ba63f5c70e455d5b245c74a216/src/interceptors/fetch/index.ts#L106

Once I wrap those (in msw and msw/cookies) in some try/catch logic, it seems like you're missing a scope response from

  return HttpResponse.json({
      id: "15d42a4d-1948-4de4-ba78-b8a893feaf45",
      firstName: "John",
+     scope: "",
    });

I'm not familiar about whether we should wrap these, or test for them somehow, and that might need a bit of prodding,

@mattcosta7
Copy link
Contributor

In the short term, I think you can use something like patch-package to make similar changes to wrap a try {} catch {} around the areas I linked above, and make the diff changes to the test - and get things looking pretty green

@mattcosta7
Copy link
Contributor

mattcosta7 commented Nov 6, 2023

once that lands we should be able to update msw and add a test in the miniflare environment to help catch regressions, while similarly checking for access in this library before before using unimplemented prototype properties in miniflare/cloudflare

It is strange to me that miniflare/cloudflare error instead of ignoring these

@monoald
Copy link
Author

monoald commented Nov 6, 2023

@mattcosta7 Thank you so much for the help! I'm about to make the changes. If the pr is accepted, for other users there is no need for them to use patch-package right?

@mattcosta7
Copy link
Contributor

mattcosta7 commented Nov 6, 2023

@mattcosta7 Thank you so much for the help! I'm about to make the changes. If the pr is accepted, for other users there is no need for them to use patch-package right?

yep - we should be able to avoid patch-package once some changes to msw are made to avoid accessing properties that throw in those environments. but may take a little bit to get those into a stable place and landed, so patching should at least unblock your progress

@monoald
Copy link
Author

monoald commented Nov 6, 2023

Great! thanks a lot again.

@monoald monoald closed this as completed Nov 6, 2023
@mattcosta7
Copy link
Contributor

I have this same issue

@Ruddickmg are you also using a worker environment like miniflare? Just want to make sure your report mirrors the one that this issue discusses

@mattcosta7 mattcosta7 changed the title TypeError: Failed to fetch TypeError: Failed to fetch in a miniflare-like environment Nov 7, 2023
@mattcosta7
Copy link
Contributor

@monoald I'll keep this open until we fix the underlying msw code to work by default if that's ok with you

@kiocosta
Copy link

kiocosta commented Nov 7, 2023

@mattcosta7 hello! I have also updated to 2.x following the migration guide and I'm facing a similar error but with a slightly different stacktrace:

TypeError: Cannot read properties of null (reading 'addEventListener')
        at globalThis.fetch (/home/kio/exp/webportal/node_modules/@mswjs/interceptors/lib/node/interceptors/fetch/index.js:51:14)
        at fetch (/home/kio/exp/webportal/src/shared/common/utils.js:74:26)
        at get (/home/kio/exp/webportal/src/cpp/rest/method/Get.js:19:28)
        at getUserDetailsRequest (/home/kio/exp/webportal/src/cpp/rest/User.js:10:24)
        at request (/home/kio/exp/webportal/src/cpp/hooks/useRequestManager/useRequestManager.jsx:36:25)
        at getUserDetails (/home/kio/exp/webportal/src/cpp/hooks/useUser/index.jsx:31:25)
        at updateStore (/home/kio/exp/webportal/src/cpp/hooks/useUser/index.jsx:49:15)
        at commitHookEffectListMount (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:23150:26)
        at commitPassiveMountOnFiber (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:24931:11)
        at commitPassiveMountEffects_complete (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:24891:9)
        at commitPassiveMountEffects_begin (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:24878:7)
        at commitPassiveMountEffects (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:24866:3)
        at flushPassiveEffectsImpl (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:27039:3)
        at flushPassiveEffects (/home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:26984:14)
        at /home/kio/exp/webportal/node_modules/react-dom/cjs/react-dom.development.js:26769:9
        at flushActQueue (/home/kio/exp/webportal/node_modules/react/cjs/react.development.js:2667:24)
        at act (/home/kio/exp/webportal/node_modules/react/cjs/react.development.js:2582:11)
        at /home/kio/exp/webportal/node_modules/@testing-library/react/dist/act-compat.js:46:25
        at renderRoot (/home/kio/exp/webportal/node_modules/@testing-library/react/dist/pure.js:161:26)
        at render (/home/kio/exp/webportal/node_modules/@testing-library/react/dist/pure.js:247:10)
        at renderHook (/home/kio/exp/webportal/node_modules/@testing-library/react/dist/pure.js:289:7)
        at Object.<anonymous> (/home/kio/exp/webportal/src/cpp/hooks/useUser/index.test.jsx:49:34)
        at Promise.then.completed (/home/kio/exp/webportal/node_modules/jest-circus/build/utils.js:298:28)
        at new Promise (<anonymous>)
        at callAsyncCircusFn (/home/kio/exp/webportal/node_modules/jest-circus/build/utils.js:231:10)
        at _callCircusTest (/home/kio/exp/webportal/node_modules/jest-circus/build/run.js:316:40)
        at processTicksAndRejections (node:internal/process/task_queues:95:5)
        at _runTest (/home/kio/exp/webportal/node_modules/jest-circus/build/run.js:252:3)
        at _runTestsForDescribeBlock (/home/kio/exp/webportal/node_modules/jest-circus/build/run.js:126:9)
        at _runTestsForDescribeBlock (/home/kio/exp/webportal/node_modules/jest-circus/build/run.js:121:9)
        at run (/home/kio/exp/webportal/node_modules/jest-circus/build/run.js:71:3)
        at runAndTransformResultsToJestFormat (/home/kio/exp/webportal/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
        at jestAdapter (/home/kio/exp/webportal/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
        at runTestInternal (/home/kio/exp/webportal/node_modules/jest-runner/build/runTest.js:367:16)
        at runTest (/home/kio/exp/webportal/node_modules/jest-runner/build/runTest.js:444:34)
        at Object.worker (/home/kio/exp/webportal/node_modules/jest-runner/build/testWorker.js:106:12)

I have Node 18.17 running. Do you think this problem is related to the problem reported by @monoald?
I have the jest.polyfills.js file created like the documentation specifies and I've linked it to jest.config.js, so I don' understand why globalThis is null in this case.

@mattcosta7
Copy link
Contributor

mattcosta7 commented Nov 7, 2023

@kiocosta almost definitely not related

your stack trace seems to be -https://github.com/mswjs/interceptors/blob/fb8a400f50ad8eb48ece32b23d8354df7e58a16e/src/interceptors/fetch/index.ts#L61

which would look like signal is null here, but it could be something else - hard to tell from just the stack here

Please open a new issue with some details about your environment and ideally a reproduction, and I can try to debug when I get a chance, but it seems as though there's some missing signal that's expected

What versions of jest and test environment (jsdom?) are you using? Curious if abort signal is not defined in that environment somewhere

@kiocosta
Copy link

kiocosta commented Nov 8, 2023

@kiocosta almost definitely not related

your stack trace seems to be -https://github.com/mswjs/interceptors/blob/fb8a400f50ad8eb48ece32b23d8354df7e58a16e/src/interceptors/fetch/index.ts#L61

which would look like signal is null here, but it could be something else - hard to tell from just the stack here

Please open a new issue with some details about your environment and ideally a reproduction, and I can try to debug when I get a chance, but it seems as though there's some missing signal that's expected

What versions of jest and test environment (jsdom?) are you using? Curious if abort signal is not defined in that environment somewhere

I'll open the issue with more details and as soon as I can.
The versions I'm using are:

    "jest": "^29.6.4",
    "jest-environment-jsdom": "^29.6.4",

@mattcosta7
Copy link
Contributor

mattcosta7 commented Nov 8, 2023

I've opened PRs in both

These 2 prs update the code which seems to cause issues in your tests, and should guard against future regressions in those dependencies, since I've added a miniflare environment test to each.

I also opened a failing test using the miniflare environment on this repo

Once we land the 2 linked prs from dependencies, and bump their versions, I expect the regression test that's failing in #1840 will pass

@kettanaito
Copy link
Member

Thanks everyone for the input on this issue. I've approved both of the pull requests Matthew mentioned, hope to get them released later today.

@kettanaito
Copy link
Member

Released: v2.0.4 🎉

This has been released in v2.0.4!

Make sure to always update to the latest version (npm i msw@latest) to get the newest features and bug fixes.


Predictable release automation by @ossjs/release.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working needs:triage Issues that have not been investigated yet. scope:node Related to MSW running in Node
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants