apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

Msw 2.0 Delay('infinite') leads to "Cannot read properties of undefined (reading 'result')" Error during vitest test.

Open itd-mge opened this issue 1 year ago • 1 comments

Hello Apollo Team, we use "@apollo/client": "3.11.8" for making gql calls. In our tests, we mock the setup via msw. After we migrated to msw 2.x and vitest, the tests are throwing strange error message if we use delay('infinite'). I tried to reproduce the error with a simpler project, but it appeared to not be so easy to reproduce it in a simpler setting. That is why I started a discussion and not a Bug Fix.

The error that appears at the end of the test is as follows:

TypeError: Cannot read properties of undefined (reading 'result')
    at handleError (/pathToNodeModules/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected][email protected]_re_ybmsh27ffbonhpnkbbd7f6s4pa/node_modules/@apollo/client/link/http/parseAndCheckHttpResponse.js:140:13)
    at /pathToNodeModules/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected][email protected]_re_ybmsh27ffbonhpnkbbd7f6s4pa/node_modules/@apollo/client/link/http/createHttpLink.js:145:17
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:538:9)
    at processTimers (node:internal/timers:512:7)

Debugging shows that in this line

export function handleError(err, observer) {
    if (err.result && err.result.errors && err.result.data) {

the handle Error is called with err as undefined. Tracing the error up the call stack did not hint us any more information. Our conclusion is that the Call promise never gets resolved in the test, since it waits for delay('infinite'). The test ends, the node environment kills the still open promise somehow, this leads the promise catching the undefined, and the test still detects the now generated error above.

Strangely, we did not patch the files shown above to prevent the error, but the http.cjs. To prevent this error, it is enough to just add an err && to the handleError:

export function handleError(err, observer) {
    if (err && err.result && err.result.errors && err.result.data) {

I think this would make the implementation in general more robust, to add this additional check.

If you have any more questions please let me know.

Thank you for your help and your great work on apollo client. :-)

itd-mge avatar Sep 30 '24 06:09 itd-mge

Hi there @itd-mge! Thanks for the detail above. I have a testing setup that uses MSW + Vite + Apollo Client I can use to try to reproduce this (used for GraphQL Testing Library tests). Will take a look and reply back with any findings, thanks!

alessbell avatar Oct 03 '24 18:10 alessbell

Hello @alessbell ,

did you make progress on that topic?

itd-cba avatar Nov 05 '24 08:11 itd-cba

Hey all 👋

Apologies for the long response time. We've been busy working on changes for 4.0. We've got a few things to wrap up, but I'm hoping we have some capacity next week to dig into this a little more. @itd-cba @itd-mge by chance do either of you have a reproduction that you can share? It would save me some time getting something setup. Thanks!

jerelmiller avatar Apr 11 '25 21:04 jerelmiller

[..] by chance do either of you have a reproduction that you can share? It would save me some time getting something setup. Thanks!

Thanks for looking into it! We're currently working on a minimal repro via codesandbox.

theMattCode avatar Apr 17 '25 12:04 theMattCode

@theMattCode awesome! I'll take a look as soon as you're able to provide the reproduction 🙂

jerelmiller avatar Apr 17 '25 17:04 jerelmiller

Hi @jerelmiller,

while building the sandbox (https://codesandbox.io/p/devbox/competent-stonebraker-srz7lp) we found out that jsdom 16.7.0 (which vitest has as a peer dependency to) introduced AbortSignal.abort() (see https://github.com/jsdom/jsdom/releases?q=16.7.0&expanded=true). We had exactly this version running and we assume, that this version was a bit buggy since it introduces the signal. The Sandbox uses exactly the buggy version and running tests very often result in the error complaining about one or more rejected promises.

Lifting the JSDOM version to a newer one (at the time of writing 26.1.0) fixed the problem.

theMattCode avatar Apr 22 '25 14:04 theMattCode

Ahhh that makes sense. Glad you found the source of the issue! As such, I'm going to go ahead and close this. Please let us know if you need any more help. Thanks a bunch!

jerelmiller avatar Apr 22 '25 14:04 jerelmiller

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

github-actions[bot] avatar Apr 22 '25 14:04 github-actions[bot]

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. For general questions, we recommend using our Community Forum or Stack Overflow.

github-actions[bot] avatar May 23 '25 00:05 github-actions[bot]