Skip to content

Commit 45dd329

Browse files
authored
feat: add eventHandler.connection.onFailed to handle connection error (#851)
Aims to resolve https://sendbird.atlassian.net/browse/CLNP-1562 Added support for `eventHandlers.connection.onFailed callback` in `setupConnection`. The new callback is invoked in case of a connection failure, providing a way to handle errors and take appropriate actions. The addition of the `onFailed` callback aims to enhance the flexibility of the `setupConnection` function, allowing users to implement custom error handling logic when a connection fails. **Example usage** ``` <Sendbird appId={appId} userId={undefined} // this will cause an error eventHandlers={{ connection: { onFailed: (error) => { alert(error?.message); // display a browser alert and print the error message inside } } }} > ``` ![Screenshot 2023-11-20 at 2 40 04 PM](https://github.com/sendbird/sendbird-uikit-react/assets/10060731/dce8d888-30ff-4160-82d7-e55c1cc358e2)
1 parent 0c9f2c2 commit 45dd329

File tree

7 files changed

+35
-2
lines changed

7 files changed

+35
-2
lines changed

src/lib/Sendbird.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ const SendbirdSDK = ({
216216
sdkDispatcher,
217217
userDispatcher,
218218
initDashboardConfigs,
219+
eventHandlers,
219220
});
220221

221222
useUnmount(() => {

src/lib/hooks/useConnect/__test__/setupConnection.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { getMissingParamError, setUpConnection, setUpParams } from '../setupConn
66
import { SetupConnectionTypes } from '../types';
77
import { generateSetUpConnectionParams, mockSdk, mockUser, mockUser2 } from './data.mocks';
88

9+
import { SendbirdError } from '@sendbird/chat';
10+
911
// todo: combine after mock-sdk is implemented
1012
jest.mock('@sendbird/chat', () => ({
1113
init: jest.fn().mockImplementation(() => mockSdk),
@@ -162,6 +164,22 @@ describe('useConnect/setupConnection', () => {
162164
type: SDK_ACTIONS.SDK_ERROR,
163165
});
164166
});
167+
168+
it('should call onConnectionFailed callback when connection fails', async () => {
169+
const onConnectionFailed = jest.fn();
170+
const setUpConnectionProps = generateSetUpConnectionParams();
171+
setUpConnectionProps.eventHandlers = { connection: { onFailed: onConnectionFailed } };
172+
173+
// Force a connection failure by providing an invalid userId
174+
const params = { ...setUpConnectionProps, userId: undefined };
175+
const expectedErrorMessage = getMissingParamError({ userId: undefined, appId: params.appId });
176+
177+
// // Ensure that the onConnectionFailed callback is called with the correct error message
178+
await expect(setUpConnection((params as unknown as SetupConnectionTypes)))
179+
.rejects.toBe(expectedErrorMessage);
180+
// Ensure that onConnectionFailed callback is called with the expected error object
181+
expect(onConnectionFailed).toHaveBeenCalledWith({ message: expectedErrorMessage } as SendbirdError);
182+
});
165183
});
166184

167185
describe('useConnect/setupConnection/setUpParams', () => {

src/lib/hooks/useConnect/connect.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export async function connect({
1919
sdkInitParams,
2020
customExtensionParams,
2121
isMobile,
22+
eventHandlers,
2223
}: ConnectTypes): Promise<void> {
2324
await disconnectSdk({
2425
logger,
@@ -42,5 +43,6 @@ export async function connect({
4243
sdkInitParams,
4344
customExtensionParams,
4445
isMobile,
46+
eventHandlers,
4547
});
4648
}

src/lib/hooks/useConnect/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function useConnect(triggerTypes: TriggerTypes, staticTypes: Stat
1818
initDashboardConfigs,
1919
sdkInitParams,
2020
customExtensionParams,
21+
eventHandlers,
2122
} = staticTypes;
2223
logger?.info?.('SendbirdProvider | useConnect', { ...triggerTypes, ...staticTypes });
2324

@@ -41,6 +42,7 @@ export default function useConnect(triggerTypes: TriggerTypes, staticTypes: Stat
4142
sdkInitParams,
4243
customExtensionParams,
4344
isMobile,
45+
eventHandlers,
4446
}).catch(error => {
4547
logger?.error?.('SendbirdProvider | useConnect/useEffect', error);
4648
});
@@ -67,6 +69,7 @@ export default function useConnect(triggerTypes: TriggerTypes, staticTypes: Stat
6769
sdkInitParams,
6870
customExtensionParams,
6971
isMobile,
72+
eventHandlers,
7073
});
7174
} catch (error) {
7275
logger?.error?.('SendbirdProvider | useConnect/reconnect/useCallback', error);

src/lib/hooks/useConnect/setupConnection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ export async function setUpConnection({
7373
sdkInitParams,
7474
customExtensionParams,
7575
isMobile = false,
76+
eventHandlers,
7677
}: SetupConnectionTypes): Promise<void> {
7778
return new Promise((resolve, reject) => {
7879
logger?.info?.('SendbirdProvider | useConnect/setupConnection/init', { userId, appId });
80+
const onConnectionFailed = eventHandlers?.connection?.onFailed;
7981
sdkDispatcher({ type: SET_SDK_LOADING, payload: true });
8082

8183
if (userId && appId) {
@@ -168,6 +170,7 @@ export async function setUpConnection({
168170
userDispatcher({ type: RESET_USER });
169171

170172
sdkDispatcher({ type: SDK_ERROR });
173+
onConnectionFailed?.(e);
171174
// exit promise with error
172175
reject(errorMessage);
173176
};
@@ -179,6 +182,7 @@ export async function setUpConnection({
179182
} else {
180183
const errorMessage = getMissingParamError({ userId, appId });
181184
sdkDispatcher({ type: SDK_ERROR });
185+
onConnectionFailed?.({ message: errorMessage } as SendbirdError);
182186
logger?.error?.(errorMessage);
183187
// exit promise with error
184188
reject(errorMessage);

src/lib/hooks/useConnect/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { UserActionTypes } from '../../dux/user/actionTypes';
77

88
import { Logger } from '../../SendbirdState';
99

10-
import { SendbirdChatInitParams, CustomExtensionParams } from '../../types';
10+
import { SendbirdChatInitParams, CustomExtensionParams, SBUEventHandlers } from '../../types';
1111

1212
type SdkDispatcher = React.Dispatch<SdkActionTypes>;
1313
type UserDispatcher = React.Dispatch<UserActionTypes>;
@@ -36,6 +36,7 @@ export type StaticTypes = {
3636
initDashboardConfigs: (sdk: SendbirdChat) => Promise<void>;
3737
sdkInitParams?: SendbirdChatInitParams;
3838
customExtensionParams?: CustomExtensionParams;
39+
eventHandlers?: SBUEventHandlers;
3940
};
4041

4142
export type ConnectTypes = TriggerTypes & StaticTypes;

src/lib/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import type SendbirdChat from '@sendbird/chat';
3-
import type { User, SendbirdChatParams } from '@sendbird/chat';
3+
import type { User, SendbirdChatParams, SendbirdError } from '@sendbird/chat';
4+
45
import type {
56
GroupChannel,
67
GroupChannelCreateParams, GroupChannelModule,
@@ -46,6 +47,9 @@ export interface SBUEventHandlers {
4647
reaction?: {
4748
onPressUserProfile?(member: User): void;
4849
},
50+
connection?: {
51+
onFailed?(error: SendbirdError): void;
52+
}
4953
}
5054

5155
export interface SendBirdStateConfig {

0 commit comments

Comments
 (0)