From 636a9c48a3ef8b36d3459071b421ccd0989fe128 Mon Sep 17 00:00:00 2001 From: djechlin-mongodb <132293929+djechlin-mongodb@users.noreply.github.com> Date: Thu, 7 Nov 2024 12:52:56 -0500 Subject: [PATCH] fix(compass-global-writes): try/catch and show error when global-writes fetch fails COMPASS-8333 (#6408) * changes * remove throw error * start tests * tests * Update packages/compass-global-writes/src/store/reducer.ts Co-authored-by: Paula Stachova * reformat --------- Co-authored-by: Paula Stachova --- .../src/store/index.spec.ts | 25 +++++++++- .../src/store/reducer.ts | 50 ++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/packages/compass-global-writes/src/store/index.spec.ts b/packages/compass-global-writes/src/store/index.spec.ts index b6e905ac54b..74a1ac056ec 100644 --- a/packages/compass-global-writes/src/store/index.spec.ts +++ b/packages/compass-global-writes/src/store/index.spec.ts @@ -72,6 +72,7 @@ function createStore({ hasShardingError = () => false, hasShardKey = () => false, failsOnShardingRequest = () => false, + failsOnShardZoneRequest = () => false, authenticatedFetchStub, }: | { @@ -79,6 +80,7 @@ function createStore({ hasShardingError?: () => boolean; hasShardKey?: () => boolean | AtlasShardKey; failsOnShardingRequest?: () => boolean; + failsOnShardZoneRequest?: () => boolean; authenticatedFetchStub?: never; } | { @@ -86,11 +88,12 @@ function createStore({ hasShardingError?: never; hasShardKey?: () => boolean | ShardKey; failsOnShardingRequest?: never; + failsOnShardZoneRequest?: () => never; authenticatedFetchStub?: () => void; } = {}): GlobalWritesStore { const atlasService = { authenticatedFetch: (uri: string) => { - if (uri.endsWith(`/geoSharding`) && failsOnShardingRequest()) { + if (uri.endsWith('/geoSharding') && failsOnShardingRequest()) { return Promise.reject(new Error('Failed to shard')); } @@ -112,6 +115,13 @@ function createStore({ }); } + if ( + /geoSharding.*newFormLocationMapping/.test(uri) && + failsOnShardZoneRequest() + ) { + return Promise.reject(new Error('Failed to fetch shard zones')); + } + return createAuthFetchResponse({}); }, automationAgentRequest: (_meta: unknown, type: string) => ({ @@ -266,6 +276,7 @@ describe('GlobalWritesStore Store', function () { const store = createStore({ isNamespaceManaged: () => true, hasShardKey: Sinon.fake(() => mockShardKey), + failsOnShardZoneRequest: () => true, }); await waitFor(() => { expect(store.getState().status).to.equal('SHARDING'); @@ -313,6 +324,18 @@ describe('GlobalWritesStore Store', function () { }); }); + it('valid shard key -> failsOnShardZoneRequest', async function () { + const store = createStore({ + isNamespaceManaged: () => true, + hasShardKey: () => true, + failsOnShardZoneRequest: () => true, + }); + await waitFor(() => { + expect(store.getState().status).to.equal('SHARD_KEY_CORRECT'); + expect(store.getState().managedNamespace).to.equal(managedNamespace); + }); + }); + it('incomplete setup -> sharding -> shard key correct', async function () { // initial state -> incomplete shardingSetup clock = sinon.useFakeTimers({ diff --git a/packages/compass-global-writes/src/store/reducer.ts b/packages/compass-global-writes/src/store/reducer.ts index 2c2279f44f3..44a655f79d3 100644 --- a/packages/compass-global-writes/src/store/reducer.ts +++ b/packages/compass-global-writes/src/store/reducer.ts @@ -30,6 +30,7 @@ enum GlobalWritesActionTypes { NamespaceShardKeyFetched = 'global-writes/NamespaceShardKeyFetched', ShardZonesFetched = 'global-writes/ShardZonesFetched', + ShardZonesFetchedError = 'global-writes/ShardZonesFetchedError', SubmittingForShardingStarted = 'global-writes/SubmittingForShardingStarted', SubmittingForShardingFinished = 'global-writes/SubmittingForShardingFinished', @@ -67,6 +68,10 @@ type ShardZonesFetchedAction = { shardZones: ShardZoneData[]; }; +type ShardZonesFetchedErrorAction = { + type: GlobalWritesActionTypes.ShardZonesFetchedError; +}; + type SubmittingForShardingStartedAction = { type: GlobalWritesActionTypes.SubmittingForShardingStarted; }; @@ -350,6 +355,18 @@ const reducer: Reducer = (state = initialState, action) => { }; } + if ( + isAction( + action, + GlobalWritesActionTypes.ShardZonesFetchedError + ) + ) { + return { + ...state, + shardZones: [], + }; + } + if ( isAction( action, @@ -880,18 +897,37 @@ export const fetchNamespaceShardKey = (): GlobalWritesThunkAction< export const fetchShardingZones = (): GlobalWritesThunkAction< Promise, - ShardZonesFetchedAction + ShardZonesFetchedAction | ShardZonesFetchedErrorAction > => { - return async (dispatch, getState, { atlasGlobalWritesService }) => { + return async ( + dispatch, + getState, + { atlasGlobalWritesService, connectionInfoRef } + ) => { const { shardZones } = getState(); if (shardZones.length > 0) { return; } - const shardingZones = await atlasGlobalWritesService.getShardingZones(); - dispatch({ - type: GlobalWritesActionTypes.ShardZonesFetched, - shardZones: shardingZones, - }); + try { + const shardingZones = await atlasGlobalWritesService.getShardingZones(); + dispatch({ + type: GlobalWritesActionTypes.ShardZonesFetched, + shardZones: shardingZones, + }); + } catch (error) { + dispatch({ + type: GlobalWritesActionTypes.ShardZonesFetchedError, + }); + openToast( + `global-writes-fetch-sharding-zones-error-${connectionInfoRef.current.id}`, + { + title: `Failed to fetch sharding zones: ${(error as Error).message}`, + dismissible: true, + timeout: 5000, + variant: 'important', + } + ); + } }; };