Skip to content

Commit ddf814b

Browse files
committed
split insertToFlagBuffer into 2 functions (insertFlagToScope and insertToFlagBuffer)
1 parent c8e8c21 commit ddf814b

File tree

3 files changed

+46
-12
lines changed

3 files changed

+46
-12
lines changed

packages/browser/src/integrations/featureFlags/launchdarkly/integration.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Client, Event, EventHint, IntegrationFn } from '@sentry/types';
22
import type { LDContext, LDEvaluationDetail, LDInspectionFlagUsedHandler } from './types';
33

44
import { defineIntegration } from '@sentry/core';
5-
import { copyFlagsFromScopeToEvent, insertToFlagBuffer } from '../../../utils/featureFlags';
5+
import { copyFlagsFromScopeToEvent, insertFlagToScope } from '../../../utils/featureFlags';
66

77
/**
88
* Sentry integration for capturing feature flags from LaunchDarkly.
@@ -46,7 +46,7 @@ export function buildLaunchDarklyFlagUsedHandler(): LDInspectionFlagUsedHandler
4646
* Handle a flag evaluation by storing its name and value on the current scope.
4747
*/
4848
method: (flagKey: string, flagDetail: LDEvaluationDetail, _context: LDContext) => {
49-
insertToFlagBuffer(flagKey, flagDetail.value);
49+
insertFlagToScope(flagKey, flagDetail.value);
5050
},
5151
};
5252
}

packages/browser/src/utils/featureFlags.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ export function copyFlagsFromScopeToEvent(event: Event): Event {
2929
}
3030

3131
/**
32-
* Insert into a FeatureFlag array while maintaining ordered LRU properties. Not
33-
* thread-safe. After inserting:
32+
* Creates a feature flags values array in current context if it does not exist
33+
* and inserts the flag into a FeatureFlag array while maintaining ordered LRU
34+
* properties. Not thread-safe. After inserting:
3435
* - `flags` is sorted in order of recency, with the newest flag at the end.
3536
* - No other flags with the same name exist in `flags`.
3637
* - The length of `flags` does not exceed `maxSize`. The oldest flag is evicted
@@ -39,19 +40,25 @@ export function copyFlagsFromScopeToEvent(event: Event): Event {
3940
* @param name Name of the feature flag to insert.
4041
* @param value Value of the feature flag.
4142
* @param maxSize Max number of flags the buffer should store. It's recommended
42-
* to keep this consistent across insertions. Default is DEFAULT_MAX_SIZE
43+
* to keep this consistent across insertions. Default is FLAG_BUFFER_SIZE
4344
*/
44-
export function insertToFlagBuffer(name: string, value: unknown, maxSize: number = FLAG_BUFFER_SIZE): void {
45-
// Currently only accepts boolean values
46-
if (typeof value !== 'boolean') {
47-
return;
48-
}
49-
45+
export function insertFlagToScope(name: string, value: unknown, maxSize: number = FLAG_BUFFER_SIZE): void {
5046
const scopeContexts = getCurrentScope().getScopeData().contexts;
5147
if (!scopeContexts.flags) {
5248
scopeContexts.flags = { values: [] };
5349
}
5450
const flags = scopeContexts.flags.values as FeatureFlag[];
51+
insertToFlagBuffer(flags, name, value, maxSize);
52+
}
53+
54+
/**
55+
* Exported for tests
56+
*/
57+
export function insertToFlagBuffer(flags: FeatureFlag[], name: string, value: unknown, maxSize: number): void {
58+
// Currently only accepts boolean values
59+
if (typeof value !== 'boolean') {
60+
return;
61+
}
5562

5663
if (flags.length > maxSize) {
5764
DEBUG_BUILD && logger.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);

packages/browser/test/utils/featureFlags.test.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1+
import { getCurrentScope } from '@sentry/core';
12
import type { FeatureFlag } from '@sentry/types';
23
import { logger } from '@sentry/utils';
34
import { vi } from 'vitest';
4-
import { insertToFlagBuffer } from '../../src/utils/featureFlags';
5+
import { insertFlagToScope, insertToFlagBuffer } from '../../src/utils/featureFlags';
56

67
describe('flags', () => {
8+
describe('insertFlagToScope()', () => {
9+
it('adds flags to the current scope context', () => {
10+
const maxSize = 3;
11+
insertFlagToScope('feat1', true, maxSize);
12+
insertFlagToScope('feat2', true, maxSize);
13+
insertFlagToScope('feat3', true, maxSize);
14+
insertFlagToScope('feat4', true, maxSize);
15+
16+
const scope = getCurrentScope();
17+
expect(scope.getScopeData().contexts.flags?.values).toEqual([
18+
{ flag: 'feat2', result: true },
19+
{ flag: 'feat3', result: true },
20+
{ flag: 'feat4', result: true },
21+
]);
22+
});
23+
});
24+
725
describe('insertToFlagBuffer()', () => {
826
const loggerSpy = vi.spyOn(logger, 'error');
927

@@ -54,6 +72,15 @@ describe('flags', () => {
5472
]);
5573
});
5674

75+
it('does not accept non-boolean values', () => {
76+
const buffer: FeatureFlag[] = [];
77+
const maxSize = 1000;
78+
insertToFlagBuffer(buffer, 'feat1', 1, maxSize);
79+
insertToFlagBuffer(buffer, 'feat2', 'string', maxSize);
80+
81+
expect(buffer).toEqual([]);
82+
});
83+
5784
it('logs error and is a no-op when buffer is larger than maxSize', () => {
5885
const buffer: FeatureFlag[] = [
5986
{ flag: 'feat1', result: true },

0 commit comments

Comments
 (0)