msw icon indicating copy to clipboard operation
msw copied to clipboard

Duplicate log output and MaxListenersExceededWarning warning (regression in 0.47.1)

Open kleinfreund opened this issue 2 years ago • 1 comments

Prerequisites

Environment check

  • [X] I'm using the latest msw version
  • [X] I'm using Node.js version 14 or higher

Browsers

Chromium (Chrome, Brave, etc.), Firefox

Reproduction repository

https://github.com/kleinfreund/kuma-gui/tree/feat/rework-dataplanes-view

Reproduction steps

  1. In package.json, change the msw dependency from 0.47.0 to ^0.47.3
  2. Run yarn install
  3. Run yarn run dev
  4. Browse around the UI and observe the console log entries

Current behavior

Many redundant log entries appear for requests that are only made once (and handled once). Example:

RestHandler.ts:183 [MSW] 09:08:29 GET http://localhost:5681/ (200 OK)

The following warning appears:

events.js:46 MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 response:mocked listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (http://localhost:8080/node_modules/.vite/deps/msw.js?v=9b1b86e7:597:19)
    at StrictEventEmitter2.addListener (http://localhost:8080/node_modules/.vite/deps/msw.js?v=9b1b86e7:608:14)
    at StrictEventEmitter2.once (http://localhost:8080/node_modules/.vite/deps/msw.js?v=9b1b86e7:868:36)
    at Object.onMockedResponse (http://localhost:8080/node_modules/.vite/deps/msw.js?v=9b1b86e7:22101:34)
ProcessEmitWarning		@	events.js:46
_addListener			@	events.js:219
addListener			@	events.js:227
StrictEventEmitter2.once	@	StrictEventEmitter.js:34
onMockedResponse		@	createRequestListener.ts:76
await in onMockedResponse (async)		
handleRequest			@	handleRequest.ts:127
await in handleRequest (async)		
(anonymous)			@	createRequestListener.ts:34
(anonymous)			@	setupWorker.ts:93

Expected behavior

The logs aren't unnecessarily redundant and there is no max listeners exceeding warning.

Notes

  • Likely cause as the only change between 0.47.0 and 0.47.1: https://github.com/mswjs/msw/pull/1392
  • Initially reported in https://github.com/mswjs/msw/issues/1343#issuecomment-1246566445
  • Code that reproduces the issue does not import msw/node

kleinfreund avatar Sep 20 '22 07:09 kleinfreund

Just want to confirm this exact issue is affecting our app too. Unable to share the full code unfortunately.

Ours is a Vite app running on React 18 and this issue started after bumping to 0.47.1.

main.tsx

const prepare = async (): Promise<ServiceWorkerRegistration | void> => {
    if (!import.meta.env.PROD) {
        const { default: worker } = await import('../stubs/browser');
        return worker.start({
            onUnhandledRequest: ({ url }, print) => {
                if (!url.pathname.includes(window.config.orchestration.url)) {
                    return;
                }
                print.warning();
            },
        });
    }
    return Promise.resolve();
};

prepare().then(() => {
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    ReactDOM.createRoot(document.getElementById('root')!).render(
        <React.StrictMode>
            <BrandProvider>
                <ThemeProvider>
                    <GlobalStyle />
                    <QueryClientProvider client={queryClient}>
                        <BrowserRouter>
                            <App />
                        </BrowserRouter>
                    </QueryClientProvider>
                </ThemeProvider>
            </BrandProvider>
        </React.StrictMode>
    );
});

stubs/browser.ts

/**
 * This file configures the mock service worker if the app is not running in PRODUCTION mode.
 */
import { SetupWorkerApi, rest, setupWorker } from 'msw';

import handlers from './handlers';

let wrk: SetupWorkerApi = {} as SetupWorkerApi;

if (!import.meta.env.PROD) {
    // Configure a Service Worker with the given request handlers
    wrk = setupWorker(...handlers);

    // @ts-ignore: store msw on window to access it in functional-test
    window.msw = {
        worker: wrk,
        rest,
    };
}

export default wrk;

ben-reitz avatar Sep 21 '22 08:09 ben-reitz

Perhaps the cause is ? https://github.com/open-draft/strict-event-emitter/pull/2

snaka avatar Sep 27 '22 14:09 snaka

@snaka That looks promising considering that https://github.com/mswjs/msw/pull/1392 introduced calls to context.emitter.once.

kleinfreund avatar Sep 27 '22 15:09 kleinfreund

@snaka, that must have been the root cause. We've just merged and released the fix to strict-event-emitter. Would anyone be interested in bumping that dependency in MSW in a pull request?

On a related note, I've noticed that https://github.com/open-draft/strict-event-emitter is heavily under-tested. If you'd like to contribute to a package we use extensively in MSW and beyond, writing tests for strict-event-emitter is a fantastic place to start!

kettanaito avatar Sep 27 '22 19:09 kettanaito

@kettanaito

I'm not sure, but is this how you want it?

https://github.com/mswjs/msw/pull/1418

snaka avatar Sep 27 '22 22:09 snaka

In case you’re running into this issue and have trouble avoiding it because you’re regenerating your lock file, you might need to pin a couple of dependencies to prevent them from being updated to a version either observes this issue or an artifact of https://github.com/mswjs/msw/pull/1407:

When using yarn, you can pin the dependencies in your package.json file like so:

{
  "// explanation for overriding msw": "https://github.com/mswjs/msw/issues/1411",
  "// explanation for overriding @mswjs/interceptors": "https://github.com/mswjs/msw/pull/1407",
  "// explanation for overriding headers-polyfill": "https://github.com/mswjs/msw/pull/1407",
  "resolutions": {
    "msw": "0.47.0",
    "msw/@mswjs/interceptors": "0.17.4",
    "msw/headers-polyfill": "3.0.4"
  }
}

Something like this can be done for npm as well using the overrides field instead.

kleinfreund avatar Sep 29 '22 10:09 kleinfreund

Released: v0.47.4 🎉

This has been released in v0.47.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.

kettanaito avatar Oct 04 '22 00:10 kettanaito