@@ -4,43 +4,45 @@ import * as Sentry from '@sentry/browser';
4
4
import type { Client as SentryClient , Event , EventHint , IntegrationFn } from '@sentry/types' ;
5
5
import type { LDContext , LDEvaluationDetail , LDInspectionFlagUsedHandler } from 'launchdarkly-js-client-sdk' ;
6
6
import type { LaunchDarklyOptions } from '../types' ;
7
+ import { insertToFlagBuffer } from '@sentry/utils' ;
7
8
8
9
/**
9
10
* Sentry integration for capturing feature flags from LaunchDarkly.
10
11
*
11
12
* See the [feature flag documentation](TODO:) for more information.
12
13
*
13
14
* @example
14
- *
15
15
* ```
16
- * TODO:
17
- * Sentry.init({
18
- * dsn: '__DSN__',
19
- * integrations: [Sentry.replayIntegration ()],
20
- * } );
16
+ * import {SentryInspector, launchDarklyIntegration} from '@sentry/launchdarkly';
17
+ * import {LDClient} from 'launchdarkly-js-client-sdk';
18
+ *
19
+ * Sentry.init(..., integrations: [launchDarklyIntegration ()])
20
+ * const ldClient = LDClient.initialize(..., inspectors: [SentryInspector] );
21
21
* ```
22
22
*/
23
23
export const launchDarklyIntegration = ( ( _options ?: LaunchDarklyOptions ) => {
24
24
return {
25
25
name : 'launchdarkly' ,
26
26
27
27
processEvent ( event : Event , _hint : EventHint , _client : SentryClient ) : Event {
28
- const scope = Sentry . getCurrentScope ( ) ; // client doesn't have getCurrentScope
29
- const flagContext = { values : scope . getFlags ( ) } ;
30
- if ( event . contexts ) {
31
- event . contexts . flags = flagContext ;
32
- } else {
33
- event . contexts = { flags : flagContext } ;
28
+ const scope = Sentry . getCurrentScope ( ) ;
29
+ const flagContext = scope . getScopeData ( ) . contexts . flags ;
30
+
31
+ if ( event . contexts === undefined ) {
32
+ event . contexts = { } ;
34
33
}
34
+ event . contexts . flags = flagContext ;
35
35
return event ;
36
36
} ,
37
37
} ;
38
38
} ) satisfies IntegrationFn ;
39
39
40
40
/**
41
41
* LaunchDarkly hook that listens for flag evaluations and updates the
42
- * flagBuffer in our current scope
43
- * TODO: finalize docstring
42
+ * flagBuffer in our current scope.
43
+ *
44
+ * This needs to be registered separately in the LDClient, after initializing
45
+ * Sentry.
44
46
*/
45
47
export class SentryInspector implements LDInspectionFlagUsedHandler {
46
48
public name = 'sentry-flag-auditor' ;
@@ -51,11 +53,16 @@ export class SentryInspector implements LDInspectionFlagUsedHandler {
51
53
public synchronous = false ;
52
54
53
55
/**
54
- * TODO: docstring
56
+ * Handle a flag evaluation by storing its name and value on the current scope.
55
57
*/
56
58
public method ( flagKey : string , flagDetail : LDEvaluationDetail , _context : LDContext ) : void {
57
59
if ( typeof flagDetail . value === 'boolean' ) {
58
- Sentry . getCurrentScope ( ) . insertFlag ( flagKey , flagDetail . value ) ;
60
+ const scopeContexts = Sentry . getCurrentScope ( ) . getScopeData ( ) . contexts ;
61
+ if ( ! scopeContexts . flags ) {
62
+ scopeContexts . flags = { values : [ ] }
63
+ }
64
+ const flagBuffer = scopeContexts . flags . values ;
65
+ insertToFlagBuffer ( flagBuffer , flagKey , flagDetail . value ) ;
59
66
}
60
67
return ;
61
68
}
0 commit comments