Skip to content

Commit 0704976

Browse files
committed
fix: Handle corrupted state in RPC tracking gracefully
- Use optional chaining for existingNetwork.rpcEndpoints - Return 'unknown' for missing/corrupted from_rpc_domain - Add test for corrupted state scenario This prevents crashes if existingNetwork lacks rpcEndpoints while still capturing analytics data to identify data integrity issues.
1 parent e6bf92c commit 0704976

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

ui/pages/settings/networks-tab/networks-form/networks-form.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,4 +646,66 @@ describe('NetworkForm Component', () => {
646646
});
647647
});
648648
});
649+
650+
it('should handle corrupted state with missing rpcEndpoints gracefully', async () => {
651+
const mockTrackEvent = jest.fn();
652+
const store = configureMockStore([thunk])({
653+
metamask: {
654+
...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }),
655+
useSafeChainsListValidation: true,
656+
orderedNetworkList: {
657+
networkId: '0x1',
658+
networkRpcUrl: 'https://mainnet.infura.io/v3/',
659+
},
660+
multichainNetworkConfigurationsByChainId:
661+
AVAILABLE_MULTICHAIN_NETWORK_CONFIGURATIONS,
662+
selectedMultichainNetworkChainId: 'eip155:1',
663+
isEvmSelected: true,
664+
},
665+
});
666+
667+
const { getByText } = renderWithProvider(
668+
<MetaMetricsContext.Provider value={mockTrackEvent}>
669+
<NetworksForm
670+
{...propNetworkDisplay}
671+
networkFormState={{
672+
...propNetworkDisplay.networkFormState,
673+
rpcUrls: {
674+
defaultRpcEndpointIndex: 0,
675+
rpcEndpoints: [
676+
{
677+
url: 'https://monad-mainnet.infura.io/v3/',
678+
type: 'custom',
679+
},
680+
],
681+
},
682+
}}
683+
existingNetwork={{
684+
chainId: '0x64',
685+
name: 'Ethereum',
686+
nativeCurrency: 'ETH',
687+
// rpcEndpoints is undefined (corrupted state)
688+
}}
689+
trackRpcUpdateFromBanner
690+
/>
691+
</MetaMetricsContext.Provider>,
692+
store,
693+
);
694+
695+
const saveButton = getByText('Save');
696+
fireEvent.click(saveButton);
697+
698+
await waitFor(() => {
699+
expect(updateNetwork).toHaveBeenCalled();
700+
expect(mockTrackEvent).toHaveBeenCalledWith({
701+
category: 'Network',
702+
event: 'Network Connection Banner RPC Updated',
703+
properties: {
704+
chain_id_caip: 'eip155:100',
705+
from_rpc_domain: 'unknown', // Corrupted state handled gracefully
706+
to_rpc_domain: 'monad-mainnet.infura.io',
707+
},
708+
});
709+
});
710+
});
649711
});

ui/pages/settings/networks-tab/networks-form/networks-form.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ export const NetworksForm = ({
320320
networkPayload.defaultRpcEndpointIndex
321321
];
322322
const oldRpcEndpoint =
323-
existingNetwork.rpcEndpoints[
323+
existingNetwork.rpcEndpoints?.[
324324
existingNetwork.defaultRpcEndpointIndex ?? 0
325325
];
326326

@@ -338,7 +338,9 @@ export const NetworksForm = ({
338338
/* eslint-disable @typescript-eslint/naming-convention */
339339
properties: {
340340
chain_id_caip: `eip155:${chainIdAsDecimal}`,
341-
from_rpc_domain: sanitizeRpcUrl(oldRpcEndpoint.url),
341+
from_rpc_domain: oldRpcEndpoint?.url
342+
? sanitizeRpcUrl(oldRpcEndpoint.url)
343+
: 'unknown',
342344
to_rpc_domain: sanitizeRpcUrl(newRpcEndpoint.url),
343345
},
344346
/* eslint-enable @typescript-eslint/naming-convention */

0 commit comments

Comments
 (0)