Skip to content

Commit 4371870

Browse files
authored
chore: Use error filter in rn event source (#322)
Pass `errorFilter` to rn eventSource to specify custom retry logic and error handling.
1 parent a343c83 commit 4371870

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

packages/sdk/react-native/src/ReactNativeLDClient.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
base64UrlEncode,
3+
BasicLogger,
34
LDClientImpl,
45
type LDContext,
56
type LDOptions,
@@ -9,7 +10,14 @@ import platform from './platform';
910

1011
export default class ReactNativeLDClient extends LDClientImpl {
1112
constructor(sdkKey: string, options: LDOptions = {}) {
12-
super(sdkKey, platform, options);
13+
const logger =
14+
options.logger ??
15+
new BasicLogger({
16+
level: 'info',
17+
// eslint-disable-next-line no-console
18+
destination: console.log,
19+
});
20+
super(sdkKey, platform, { ...options, logger });
1321
}
1422

1523
override createStreamUriPath(context: LDContext) {

packages/sdk/react-native/src/platform.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import RNEventSource from './react-native-sse';
2222

2323
class PlatformRequests implements Requests {
2424
createEventSource(url: string, eventSourceInitDict: EventSourceInitDict): EventSource {
25-
// TODO: add retry logic
26-
return new RNEventSource<EventName>(url, eventSourceInitDict);
25+
return new RNEventSource<EventName>(url, {
26+
headers: eventSourceInitDict.headers,
27+
retryAndHandleError: eventSourceInitDict.errorFilter,
28+
});
2729
}
2830

2931
fetch(url: string, options?: Options): Promise<Response> {

packages/sdk/react-native/src/react-native-sse/EventSource.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ const defaultOptions: EventSourceOptions = {
1717
method: 'GET',
1818
pollingInterval: 5000,
1919
timeout: 0,
20-
timeoutBeforeConnection: 500,
20+
timeoutBeforeConnection: 0,
2121
withCredentials: false,
22+
retryAndHandleError: undefined,
2223
};
2324

2425
export default class EventSource<E extends string = never> {
@@ -49,6 +50,7 @@ export default class EventSource<E extends string = never> {
4950
private xhr: XMLHttpRequest = new XMLHttpRequest();
5051
private pollTimer: any;
5152
private pollingInterval: number;
53+
private retryAndHandleError?: (err: any) => boolean;
5254

5355
constructor(url: string, options?: EventSourceOptions) {
5456
const opts = {
@@ -65,6 +67,7 @@ export default class EventSource<E extends string = never> {
6567
this.body = opts.body;
6668
this.debug = opts.debug!;
6769
this.pollingInterval = opts.pollingInterval!;
70+
this.retryAndHandleError = opts.retryAndHandleError;
6871

6972
this.pollAgain(this.timeoutBeforeConnection, true);
7073
}
@@ -147,7 +150,21 @@ export default class EventSource<E extends string = never> {
147150

148151
if (this.xhr.readyState === XMLHttpRequest.DONE) {
149152
this.logDebug('[EventSource][onreadystatechange][ERROR] Response status error.');
150-
this.pollAgain(this.pollingInterval, false);
153+
154+
if (!this.retryAndHandleError) {
155+
// default implementation
156+
this.pollAgain(this.pollingInterval, false);
157+
} else {
158+
// custom retry logic
159+
const shouldRetry = this.retryAndHandleError({
160+
status: this.xhr.status,
161+
message: this.xhr.responseText,
162+
});
163+
164+
if (shouldRetry) {
165+
this.pollAgain(this.pollingInterval, true);
166+
}
167+
}
151168
}
152169
}
153170
};
@@ -290,7 +307,7 @@ export default class EventSource<E extends string = never> {
290307
this.onerror(data);
291308
break;
292309
case 'retry':
293-
this.onretrying();
310+
this.onretrying({ delayMillis: this.pollingInterval });
294311
break;
295312
default:
296313
break;
@@ -310,5 +327,5 @@ export default class EventSource<E extends string = never> {
310327
onopen() {}
311328
onclose() {}
312329
onerror(_err: any) {}
313-
onretrying() {}
330+
onretrying(_e: any) {}
314331
}

packages/sdk/react-native/src/react-native-sse/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface EventSourceOptions {
5353
body?: any;
5454
debug?: boolean;
5555
pollingInterval?: number;
56+
retryAndHandleError?: (err: any) => boolean;
5657
}
5758

5859
type BuiltInEventMap = {

0 commit comments

Comments
 (0)