diff --git a/packages/selected-network-controller/src/SelectedNetworkController.ts b/packages/selected-network-controller/src/SelectedNetworkController.ts index e6a8b904bde..8f73418122a 100644 --- a/packages/selected-network-controller/src/SelectedNetworkController.ts +++ b/packages/selected-network-controller/src/SelectedNetworkController.ts @@ -283,13 +283,16 @@ export class SelectedNetworkController extends BaseController< 'NetworkController:getNetworkClientById', networkClientId, ); - const networkProxy = this.getProviderAndBlockTracker(domain); - networkProxy.provider.setTarget(networkClient.provider); - networkProxy.blockTracker.setTarget(networkClient.blockTracker); + // This needs to happen before getProviderAndBlockTracker, + // otherwise we may be referencing a network client ID that no longer exists. this.update((state) => { state.domains[domain] = networkClientId; }); + + const networkProxy = this.getProviderAndBlockTracker(domain); + networkProxy.provider.setTarget(networkClient.provider); + networkProxy.blockTracker.setTarget(networkClient.blockTracker); } /** diff --git a/packages/selected-network-controller/tests/SelectedNetworkController.test.ts b/packages/selected-network-controller/tests/SelectedNetworkController.test.ts index b59a977d5c8..fd975016ca1 100644 --- a/packages/selected-network-controller/tests/SelectedNetworkController.test.ts +++ b/packages/selected-network-controller/tests/SelectedNetworkController.test.ts @@ -363,6 +363,52 @@ describe('SelectedNetworkController', () => { 'deleted-network.com': networkControllerState.selectedNetworkClientId, }); }); + + it('redirects domains to the globally selected network when useRequestQueuePreference is true and handles garbage collected proxies', () => { + const domainProxyMap = new Map(); + const { + controller, + messenger, + mockNetworkControllerGetState, + mockGetNetworkClientById, + } = setup({ + state: { domains: initialDomains }, + useRequestQueuePreference: true, + domainProxyMap, + }); + + // Simulate proxies being garbage collected + domainProxyMap.clear(); + + const networkControllerState = { + ...getDefaultNetworkControllerState(), + selectedNetworkClientId: 'mainnet', + }; + + mockGetNetworkClientById.mockImplementation((id) => { + // Simulate the previous domain being deleted in NetworkController + if (id !== 'mainnet') { + throw new Error('Network client does not exist'); + } + + return { + provider: { request: jest.fn() }, + blockTracker: { getLatestBlock: jest.fn() }, + }; + }); + + deleteNetwork( + '0x5', + networkControllerState, + messenger, + mockNetworkControllerGetState, + ); + + expect(controller.state.domains).toStrictEqual({ + ...initialDomains, + 'deleted-network.com': networkControllerState.selectedNetworkClientId, + }); + }); }); describe('when a network is updated', () => {