Overriding global $fetch with `ofetch.create` will break the test run
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 437
- Forks
- 120
- Avg merge
- 22h 52m
- Merged PRs (30d)
- 23
Description
Environment
Nuxt project info:
- Operating System: Linux
- Node Version: v18.18.0
- Nuxt Version: 3.11.1
- CLI Version: 3.11.0
- Nitro Version: 2.9.4
- Package Manager: npm@10.2.3
- Builder: -
- User Config: devtools
- Runtime Modules: -
- Build Modules: -
@nuxt/test-utils version: 3.12.0
vitest version: 1.4.0
Reproduction
Here is a reproduce stackblitz: https://stackblitz.com/edit/github-lxyzpn?file=plugins%2Fonrequest.client.ts
Create a plugin that will override the default $fetch. This is handy when trying to inject your own headers into the HTTP requests. If you google this, you will find a helpful SO solution: https://stackoverflow.com/a/75871291/216846
import { ofetch } from 'ofetch';
export default defineNuxtPlugin((_nuxtApp) => {
globalThis.$fetch = ofetch.create({ // <- this is the important part!
onRequest({ request, options }) {
options.headers = { Authorization: `Bearer token` };
console.log('onRequest', request);
},
onRequestError({ error }) {
console.log(error);
},
});
});
This works fine when running the dev environment or prod environment. When you now run @nuxt/test-utils based test case, the tests pass, but the run fails to this error (see the whole log in logs):
TypeError: Cannot set property request of FetchError: [GET] "/_nuxt/builds/meta/test.json": <no response> Failed to parse URL from /_nuxt/builds/meta/test.json which has only a getter
Describe the bug
The correct way to implement this kind of plugin that edits the HTTP requests is described here: https://nuxt.com/docs/examples/advanced/use-custom-fetch-composable. Instead of returning you just inject the globalThis.$fetch with the created fetch instance.
The bug is that in dev and prod environments you can as well do it like this globalThis.$fetch = ofetch.create. Everything works, except when you run unit tests with @nuxt/test-utils, you get errors described above.
So, again, the correct way is to do globalThis.$fetch = $fetch.create but I think there should be a warning or something guiding the devs to do it correctly. Or at least they find this bug issue and can fix it in their code.
Additional context
No response
Logs
~/projects/vbwirlala.github 4m 11s
❯ npm run test
> test
> vitest
DEV v1.4.0 /home/projects/vbwirlala.github
stdout | Object.onRequest (/home/projects/vbwirlala.github/plugins/onrequest.client.ts:8:15)
onRequest /_nuxt/builds/meta/test.json
onRequest /_nuxt/builds/meta/test.json
stdout | Object.onRequestError (/home/projects/vbwirlala.github/plugins/onrequest.client.ts:11:15)
TypeError: Failed to parse URL from /_nuxt/builds/meta/test.json
at _0x88e3f9 (https://vbwirlalagithub-bvqi.w-credentialless-staticblitz.com/blitz.810981ba.js:352:614955)
at _0x303d3a._0x5ec96b (https://vbwirlalagithub-bvqi.w-credentialless-staticblitz.com/blitz.810981ba.js:352:625681)
at Object.t.exports.fetch (node:internal/deps/undici/undici:194:308109)
at $fetchRaw2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:236:26)
at $fetch2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:278:15) {
[cause]: TypeError [ERR_INVALID_URL]: Invalid URL
at __node_internal_ (node:internal/errors:36:5406)
at new <anonymous> (node:internal/errors:36:4168)
at new URL (node:internal/url:48:8018)
at new URL (/home/projects/vbwirlala.github/node_modules/happy-dom/lib/url/URL.js:25:1)
at new oe (node:internal/deps/undici/undici:194:83653)
at fetch (node:internal/deps/undici/undici:194:307099)
at Object.t.exports.fetch (node:internal/deps/undici/undici:194:308078)
at node:internal/process/pre_execution:56:2507
at $fetchRaw2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:236:32)
at $fetch2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:278:15) {
input: '/_nuxt/builds/meta/test.json',
code: 'ERR_INVALID_URL'
}
}
TypeError: Failed to parse URL from /_nuxt/builds/meta/test.json
at _0x88e3f9 (https://vbwirlalagithub-bvqi.w-credentialless-staticblitz.com/blitz.810981ba.js:352:614955)
at _0x303d3a._0x5ec96b (https://vbwirlalagithub-bvqi.w-credentialless-staticblitz.com/blitz.810981ba.js:352:625681)
at Object.t.exports.fetch (node:internal/deps/undici/undici:194:308109)
at $fetchRaw2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:236:26)
at $fetchRaw2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:245:14)
at $fetch2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:278:15) {
[cause]: TypeError [ERR_INVALID_URL]: Invalid URL
at __node_internal_ (node:internal/errors:36:5406)
at new <anonymous> (node:internal/errors:36:4168)
at new URL (node:internal/url:48:8018)
at new URL (/home/projects/vbwirlala.github/node_modules/happy-dom/lib/url/URL.js:25:1)
at new oe (node:internal/deps/undici/undici:194:83653)
at fetch (node:internal/deps/undici/undici:194:307099)
at Object.t.exports.fetch (node:internal/deps/undici/undici:194:308078)
at node:internal/process/pre_execution:56:2507
at $fetchRaw2 (/home/projects/vbwirlala.github/node_modules/ofetch/dist/shared/ofetch.00501375.mjs:236:32) {
input: '/_nuxt/builds/meta/test.json',
code: 'ERR_INVALID_URL'
}
}
stdout | createSuspenseBoundary (/home/projects/vbwirlala.github/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:1442:43)
<Suspense> is an experimental feature and its API will likely change.
✓ test/my.spec.ts (1)
✓ abba (1)
✓ should be abba
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
TypeError: Cannot set property request of FetchError: [GET] "/_nuxt/builds/meta/test.json": <no response> Failed to parse URL from /_nuxt/builds/meta/test.json which has only a getter
❯ _0x46d1e6 ../../../blitz.810981ba.js:352:617597
❯ _0x1eee56 ../../../blitz.810981ba.js:352:615189
❯ FetchError.get ../../../blitz.810981ba.js:352:615388
❯ Module.processError node_modules/@vitest/utils/dist/error.js:95:11
❯ catchError node_modules/vitest/dist/vendor/execute.2_yoIC01.js:396:39
❯ process.unhandledRejection node_modules/vitest/dist/vendor/execute.2_yoIC01.js:406:37
❯ EventEmitter.emit node:events:42:9202
❯ emit node:internal/process/promises:230:1176
❯ processPromiseRejections node:internal/process/promises:230:3782
❯ processTicksAndRejections node:internal/process/task_queues:107:1089
This error originated in "test/my.spec.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Test Files 1 passed (1)
Tests 1 passed (1)
Errors 1 error
Start at 08:55:23
Duration 4.31s (transform 467ms, setup 535ms, collect 11ms, tests 2ms, environment 800ms, prepare 1.37s)
FAIL Tests failed. Watching for file changes...
press h to show help, press q to quit
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the StackBlitz reproduction, especially plugins/onrequest.client.ts and test/my.spec.ts, and trace how @nuxt/test-utils handles an overridden globalThis.$fetch during its metadata request. Reproduce the unhandled error with the reported Nuxt and Vitest versions, then establish a regression check and the supported outcome for this configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nuxt, typescript
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100