Skip to content

Commit e61c9c3

Browse files
authored
feat(compass-web): add onFailToLoadConnections callback COMPASS-8657 (#6599)
* feat(connections): add onFailToLoadConnections callback for error handling * fix ci and add test
1 parent 0ca8439 commit e61c9c3

File tree

8 files changed

+82
-6
lines changed

8 files changed

+82
-6
lines changed

configs/testing-library-compass/src/index.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ type TestConnectionsOptions = {
9393
connectFn?: (
9494
connectionOptions: ConnectionInfo['connectionOptions']
9595
) => Partial<DataService> | Promise<Partial<DataService>>;
96+
/**
97+
* Connection storage mock
98+
*/
99+
connectionStorage?: ConnectionStorage;
96100
} & Partial<
97101
Omit<
98102
React.ComponentProps<typeof CompassConnections>,
@@ -258,9 +262,9 @@ function createWrapper(
258262
preferences: new InMemoryPreferencesAccess(options.preferences),
259263
track: Sinon.stub(),
260264
logger: createNoopLogger(),
261-
connectionStorage: new InMemoryConnectionStorage(
262-
options.connections
263-
) as ConnectionStorage,
265+
connectionStorage:
266+
options.connectionStorage ??
267+
(new InMemoryConnectionStorage(options.connections) as ConnectionStorage),
264268
connectionsStore: {
265269
getState: undefined as unknown as () => State,
266270
actions: {} as ReturnType<typeof useConnectionActions>,
@@ -330,6 +334,12 @@ function createWrapper(
330334
<ConnectFnProvider connect={wrapperState.connect}>
331335
<CompassConnections
332336
appName={options.appName ?? 'TEST'}
337+
onFailToLoadConnections={
338+
options.onFailToLoadConnections ??
339+
(() => {
340+
// noop
341+
})
342+
}
333343
onExtraConnectionDataRequest={
334344
options.onExtraConnectionDataRequest ??
335345
(() => {

packages/compass-connections/src/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ const ConnectionsComponent: React.FunctionComponent<{
6363
* connections on plugin activate
6464
*/
6565
preloadStorageConnectionInfos?: ConnectionInfo[];
66+
/**
67+
* When connections fail to load, this callback will be called
68+
*/
69+
onFailToLoadConnections: (error: Error) => void;
6670
}> = ({ children }) => {
6771
return (
6872
<ConnectionActionsProvider>
@@ -90,6 +94,7 @@ const CompassConnectionsPlugin = registerHadronPlugin(
9094
appName: initialProps.appName,
9195
connectFn: initialProps.connectFn,
9296
globalAppRegistry,
97+
onFailToLoadConnections: initialProps.onFailToLoadConnections,
9398
});
9499

95100
setTimeout(() => {

packages/compass-connections/src/stores/connections-store-redux.spec.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
render,
1010
} from '@mongodb-js/testing-library-compass';
1111
import React from 'react';
12+
import { InMemoryConnectionStorage } from '@mongodb-js/connection-storage/provider';
1213

1314
const mockConnections = [
1415
{
@@ -48,6 +49,30 @@ describe('CompassConnections store', function () {
4849
sinon.restore();
4950
});
5051

52+
describe('#loadAll', function () {
53+
it('calls onFailToLoadConnections when it fails to loadAll connections', async function () {
54+
const onFailToLoadConnectionsSpy = sinon.spy();
55+
const connectionStorage = new InMemoryConnectionStorage();
56+
connectionStorage.loadAll = sinon
57+
.stub()
58+
.rejects(new Error('loadAll failed'));
59+
60+
renderCompassConnections({
61+
connectionStorage,
62+
onFailToLoadConnections: onFailToLoadConnectionsSpy,
63+
});
64+
65+
await waitFor(() => {
66+
expect(onFailToLoadConnectionsSpy).to.have.been.calledOnce;
67+
});
68+
69+
expect(onFailToLoadConnectionsSpy.firstCall.firstArg).to.have.property(
70+
'message',
71+
'loadAll failed'
72+
);
73+
});
74+
});
75+
5176
describe('#connect', function () {
5277
it('should show notifications throughout connection flow and save connection to persistent store', async function () {
5378
const { connectionsStore, connectionStorage, track } =

packages/compass-connections/src/stores/connections-store-redux.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ type ThunkExtraArg = {
216216
) => Promise<[ExtraConnectionDataForTelemetry, string | null]>;
217217
connectFn?: typeof devtoolsConnect;
218218
globalAppRegistry: Pick<AppRegistry, 'on' | 'emit' | 'removeListener'>;
219+
onFailToLoadConnections: (error: Error) => void;
219220
};
220221

221222
export type ConnectionsThunkAction<
@@ -1266,7 +1267,11 @@ export const loadConnections = (): ConnectionsThunkAction<
12661267
| ConnectionsLoadSuccessAction
12671268
| ConnectionsLoadErrorAction
12681269
> => {
1269-
return async (dispatch, getState, { connectionStorage }) => {
1270+
return async (
1271+
dispatch,
1272+
getState,
1273+
{ connectionStorage, onFailToLoadConnections }
1274+
) => {
12701275
if (getState().connections.status !== 'initial') {
12711276
return;
12721277
}
@@ -1276,6 +1281,7 @@ export const loadConnections = (): ConnectionsThunkAction<
12761281
dispatch({ type: ActionTypes.ConnectionsLoadSuccess, connections });
12771282
} catch (err) {
12781283
dispatch({ type: ActionTypes.ConnectionsLoadError, error: err as any });
1284+
onFailToLoadConnections(err as Error);
12791285
}
12801286
};
12811287
};

packages/compass-web/sandbox/index.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
import React, { useLayoutEffect, useRef } from 'react';
1+
import React, { useCallback, useLayoutEffect, useRef } from 'react';
22
import ReactDOM from 'react-dom';
3-
import { resetGlobalCSS, css, Body } from '@mongodb-js/compass-components';
3+
import {
4+
resetGlobalCSS,
5+
css,
6+
Body,
7+
openToast,
8+
} from '@mongodb-js/compass-components';
49
import type { AllPreferences } from 'compass-preferences-model';
510
import { CompassWeb } from '../src/index';
611
import { SandboxConnectionStorageProvider } from '../src/connection-storage';
@@ -87,6 +92,14 @@ const App = () => {
8792
getMetaEl('csrf-time').setAttribute('content', csrfTime ?? '');
8893
}, [csrfToken, csrfTime]);
8994

95+
const onFailToLoadConnections = useCallback((error: Error) => {
96+
openToast('failed-to-load-connections', {
97+
title: 'Failed to load connections',
98+
description: error.message,
99+
variant: 'warning',
100+
});
101+
}, []);
102+
90103
if (status === 'checking') {
91104
return null;
92105
}
@@ -133,6 +146,7 @@ const App = () => {
133146
onTrack={sandboxTelemetry.track}
134147
onDebug={sandboxLogger.debug}
135148
onLog={sandboxLogger.log}
149+
onFailToLoadConnections={onFailToLoadConnections}
136150
></CompassWeb>
137151
</Body>
138152
</SandboxPreferencesUpdateProvider>

packages/compass-web/src/entrypoint.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ describe('CompassWeb', function () {
7474
enableCreatingNewConnections: true,
7575
...props.initialPreferences,
7676
}}
77+
onFailToLoadConnections={() => {}}
7778
></CompassWeb>
7879
</ConnectFnProvider>
7980
);

packages/compass-web/src/entrypoint.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ type CompassWebProps = {
150150
onOpenConnectViaModal?: (
151151
atlasMetadata: ConnectionInfo['atlasMetadata']
152152
) => void;
153+
154+
/**
155+
* Callback prop called when connections fail to load
156+
*/
157+
onFailToLoadConnections: (err: Error) => void;
153158
};
154159

155160
function CompassWorkspace({
@@ -253,6 +258,7 @@ const CompassWeb = ({
253258
onDebug,
254259
onTrack,
255260
onOpenConnectViaModal,
261+
onFailToLoadConnections,
256262
}: CompassWebProps) => {
257263
const appRegistry = useRef(new AppRegistry());
258264
const logger = useCompassWebLoggerAndTelemetry({
@@ -335,6 +341,7 @@ const CompassWeb = ({
335341
>
336342
<CompassConnections
337343
appName={appName ?? 'Compass Web'}
344+
onFailToLoadConnections={onFailToLoadConnections}
338345
onExtraConnectionDataRequest={() => {
339346
return Promise.resolve([{}, null] as [
340347
Record<string, unknown>,

packages/compass/src/app/components/home.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
css,
77
cx,
88
getScrollbarStyles,
9+
openToast,
910
palette,
1011
resetGlobalCSS,
1112
} from '@mongodb-js/compass-components';
@@ -149,6 +150,13 @@ function HomeWithConnections({
149150
onExtraConnectionDataRequest={getExtraConnectionData}
150151
onAutoconnectInfoRequest={onAutoconnectInfoRequest}
151152
doNotReconnectDisconnectedAutoconnectInfo
153+
onFailToLoadConnections={(error) => {
154+
openToast('failed-to-load-connections', {
155+
title: 'Failed to load connections',
156+
description: error.message,
157+
variant: 'warning',
158+
});
159+
}}
152160
>
153161
<Home {...props}></Home>
154162
</CompassConnections>

0 commit comments

Comments
 (0)