Skip to content

Commit 3b7030b

Browse files
committed
More robust max pending event handling.
1 parent b6852d2 commit 3b7030b

File tree

3 files changed

+59
-19
lines changed

3 files changed

+59
-19
lines changed

packages/telemetry/browser-telemetry/__tests__/BrowserTelemetryImpl.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,37 @@ it('unregisters collectors on close', () => {
208208

209209
expect(mockCollector.unregister).toHaveBeenCalled();
210210
});
211+
212+
it('logs event dropped message when maxPendingEvents is reached', () => {
213+
const mockLogger = {
214+
warn: jest.fn(),
215+
};
216+
const telemetry = new BrowserTelemetryImpl({
217+
...defaultOptions,
218+
breadcrumbs: {
219+
maxBreadcrumbs: 2,
220+
click: false,
221+
keyboardInput: false,
222+
http: {
223+
instrumentFetch: false,
224+
instrumentXhr: false,
225+
},
226+
evaluations: false,
227+
flagChange: false,
228+
},
229+
maxPendingEvents: 2,
230+
logger: mockLogger,
231+
});
232+
telemetry.captureError(new Error('Test error'));
233+
expect(mockLogger.warn).not.toHaveBeenCalled();
234+
telemetry.captureError(new Error('Test error 2'));
235+
expect(mockLogger.warn).not.toHaveBeenCalled();
236+
237+
telemetry.captureError(new Error('Test error 3'));
238+
expect(mockLogger.warn).toHaveBeenCalledWith(
239+
'LaunchDarkly - Browser Telemetry: Maximim pending events reached. Old events will be dropped until the SDK' +
240+
' client is registered.');
241+
242+
telemetry.captureError(new Error('Test error 4'));
243+
expect(mockLogger.warn).toHaveBeenCalledTimes(1)
244+
});

packages/telemetry/browser-telemetry/src/BrowserTelemetryImpl.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export default class BrowserTelemetryImpl implements BrowserTelemetry {
8383

8484
private _logger: MinLogger;
8585

86+
// Used to ensure we only log the event dropped message once.
87+
private _eventsDropped: boolean = false;
88+
8689
constructor(private _options: ParsedOptions) {
8790
configureTraceKit(_options.stack);
8891

@@ -168,11 +171,14 @@ export default class BrowserTelemetryImpl implements BrowserTelemetry {
168171
if (this._client === undefined) {
169172
this._pendingEvents.push({ type, data: event });
170173
if (this._pendingEvents.length > this._maxPendingEvents) {
171-
this._logger.warn(
172-
prefixLog(
173-
`Dropping ${this._pendingEvents.length - this._maxPendingEvents} pending events.`,
174-
),
175-
);
174+
if (!this._eventsDropped) {
175+
this._eventsDropped = true;
176+
this._logger.warn(
177+
prefixLog(
178+
`Maximim pending events reached. Old events will be dropped until the SDK client is registered.`,
179+
),
180+
);
181+
}
176182
this._pendingEvents.shift();
177183
}
178184
}
@@ -184,20 +190,20 @@ export default class BrowserTelemetryImpl implements BrowserTelemetry {
184190

185191
const data: ErrorData = validException
186192
? {
187-
type: exception.name || exception.constructor?.name || GENERIC_EXCEPTION,
188-
// Only coalesce null/undefined, not empty.
189-
message: exception.message ?? MISSING_MESSAGE,
190-
stack: parse(exception, this._options.stack),
191-
breadcrumbs: [...this._breadcrumbs],
192-
sessionId: this._sessionId,
193-
}
193+
type: exception.name || exception.constructor?.name || GENERIC_EXCEPTION,
194+
// Only coalesce null/undefined, not empty.
195+
message: exception.message ?? MISSING_MESSAGE,
196+
stack: parse(exception, this._options.stack),
197+
breadcrumbs: [...this._breadcrumbs],
198+
sessionId: this._sessionId,
199+
}
194200
: {
195-
type: GENERIC_EXCEPTION,
196-
message: NULL_EXCEPTION_MESSAGE,
197-
stack: { frames: [] },
198-
breadcrumbs: [...this._breadcrumbs],
199-
sessionId: this._sessionId,
200-
};
201+
type: GENERIC_EXCEPTION,
202+
message: NULL_EXCEPTION_MESSAGE,
203+
stack: { frames: [] },
204+
breadcrumbs: [...this._breadcrumbs],
205+
sessionId: this._sessionId,
206+
};
201207
this._capture(ERROR_KEY, data);
202208
}
203209

packages/telemetry/browser-telemetry/src/collectors/http/fetchDecorator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default function decorateFetch(callback: (breadcrumb: HttpBreadcrumb) =>
7777
return response;
7878
});
7979
}
80-
wrapper.prototype = originalFetch.prototype;
80+
wrapper.prototype = originalFetch?.prototype;
8181

8282
try {
8383
// Use defineProperty to prevent this value from being enumerable.

0 commit comments

Comments
 (0)