From 3c2d2be63a480816788cd6355013e220fb4de573 Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 28 May 2025 21:53:54 +0600 Subject: [PATCH 1/4] throw error from createUserContext in case of invalid input --- lib/optimizely/index.tests.js | 20 +++++++++++--------- lib/optimizely/index.ts | 14 ++++++++++---- lib/shared_types.ts | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/optimizely/index.tests.js b/lib/optimizely/index.tests.js index 20debfe31..7da2cd8c3 100644 --- a/lib/optimizely/index.tests.js +++ b/lib/optimizely/index.tests.js @@ -17,7 +17,7 @@ import { assert, expect } from 'chai'; import sinon from 'sinon'; import { sprintf } from '../utils/fns'; import { NOTIFICATION_TYPES } from '../notification_center/type'; -import Optimizely from './'; +import Optimizely, { INVALID_ATTRIBUTES, INVALID_IDENTIFIER } from './'; import OptimizelyUserContext from '../optimizely_user_context'; import { OptimizelyDecideOption } from '../shared_types'; import AudienceEvaluator from '../core/audience_evaluator'; @@ -4379,14 +4379,16 @@ describe('lib/optimizely', function() { assert.deepEqual(userId, user.getUserId()); }); - it('should return null OptimizelyUserContext when input userId is null', function() { - var user = optlyInstance.createUserContext(null); - assert.deepEqual(null, user); + it('should throw error when input userId is null', function() { + assert.throws(() => { + optlyInstance.createUserContext(null); + }, Error, INVALID_IDENTIFIER); }); - it('should return null OptimizelyUserContext when input userId is undefined', function() { - var user = optlyInstance.createUserContext(undefined); - assert.deepEqual(null, user); + it('should throw error when input userId is undefined', function() { + assert.throws(() => { + optlyInstance.createUserContext(undefined); + }, Error, INVALID_IDENTIFIER); }); it('should create multiple instances of OptimizelyUserContext', function() { @@ -4409,7 +4411,7 @@ describe('lib/optimizely', function() { const { optlyInstance, errorNotifier, createdLogger } = getOptlyInstance({ datafileObj: testData.getTestDecideProjectConfig(), }); - assert.isNull(optlyInstance.createUserContext(1)); + assert.throws(() => optlyInstance.createUserContext(1), Error, INVALID_IDENTIFIER); sinon.assert.calledOnce(errorNotifier.notify); // var errorMessage = errorHandler.handleError.lastCall.args[0].message; // assert.strictEqual(errorMessage, sprintf(INVALID_INPUT_FORMAT, 'OPTIMIZELY', 'user_id')); @@ -4422,7 +4424,7 @@ describe('lib/optimizely', function() { const { optlyInstance, errorNotifier, createdLogger } = getOptlyInstance({ datafileObj: testData.getTestDecideProjectConfig(), }); - assert.isNull(optlyInstance.createUserContext('user1', 'invalid_attributes')); + assert.throws(() => optlyInstance.createUserContext('user1', 'invalid_attributes'), Error, INVALID_ATTRIBUTES); sinon.assert.calledOnce(errorNotifier.notify); // var errorMessage = errorHandler.handleError.lastCall.args[0].message; // assert.strictEqual(errorMessage, sprintf(INVALID_ATTRIBUTES, 'ATTRIBUTES_VALIDATOR')); diff --git a/lib/optimizely/index.ts b/lib/optimizely/index.ts index 0d6c937f8..e4f3cd089 100644 --- a/lib/optimizely/index.ts +++ b/lib/optimizely/index.ts @@ -114,6 +114,8 @@ type DecisionReasons = (string | number)[]; export const INSTANCE_CLOSED = 'Instance closed'; export const ONREADY_TIMEOUT = 'onReady timeout expired after %s ms'; +export const INVALID_IDENTIFIER = 'Invalid identifier'; +export const INVALID_ATTRIBUTES = 'Invalid attributes'; /** * options required to create optimizely object @@ -1356,13 +1358,17 @@ export default class Optimizely extends BaseService implements Client { * @param {string} userId (Optional) The user ID to be used for bucketing. * @param {UserAttributes} attributes (Optional) user attributes. * @return {OptimizelyUserContext|null} An OptimizelyUserContext associated with this OptimizelyClient or - * null if provided inputs are invalid + * throws if provided inputs are invalid */ - createUserContext(userId?: string, attributes?: UserAttributes): OptimizelyUserContext | null { + createUserContext(userId?: string, attributes?: UserAttributes): OptimizelyUserContext { const userIdentifier = userId ?? this.vuidManager?.getVuid(); - if (userIdentifier === undefined || !this.validateInputs({ user_id: userIdentifier }, attributes)) { - return null; + if (userIdentifier === undefined || !this.validateInputs({ user_id: userIdentifier })) { + throw new Error(INVALID_IDENTIFIER); + } + + if (!this.validateInputs({ user_id: userIdentifier }, attributes)) { + throw new Error(INVALID_ATTRIBUTES); } const userContext = new OptimizelyUserContext({ diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 0a1582e4a..93d5d4524 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -293,7 +293,7 @@ export interface OptimizelyVariable { export interface Client { // TODO: In the future, will add a function to allow overriding the VUID. getVuid(): string | undefined; - createUserContext(userId?: string, attributes?: UserAttributes): OptimizelyUserContext | null; + createUserContext(userId?: string, attributes?: UserAttributes): OptimizelyUserContext; notificationCenter: NotificationCenter; activate(experimentKey: string, userId: string, attributes?: UserAttributes): string | null; track(eventKey: string, userId: string, attributes?: UserAttributes, eventTags?: EventTags): void; From 81e0ffd6a30eed5e27fea935e4caa1a5b76faf1d Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 28 May 2025 21:57:56 +0600 Subject: [PATCH 2/4] up --- lib/optimizely/index.tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/optimizely/index.tests.js b/lib/optimizely/index.tests.js index 7da2cd8c3..75d631695 100644 --- a/lib/optimizely/index.tests.js +++ b/lib/optimizely/index.tests.js @@ -4407,7 +4407,7 @@ describe('lib/optimizely', function() { assert.deepEqual(user2.getUserId(), userId2); }); - it('should call the error handler for invalid user ID and return null', function() { + it('should call the error handler for invalid user ID and return throw', function() { const { optlyInstance, errorNotifier, createdLogger } = getOptlyInstance({ datafileObj: testData.getTestDecideProjectConfig(), }); @@ -4420,7 +4420,7 @@ describe('lib/optimizely', function() { // assert.strictEqual(logMessage, sprintf(INVALID_INPUT_FORMAT, 'OPTIMIZELY', 'user_id')); }); - it('should call the error handler for invalid attributes and return null', function() { + it('should call the error handler for invalid attributes and throw', function() { const { optlyInstance, errorNotifier, createdLogger } = getOptlyInstance({ datafileObj: testData.getTestDecideProjectConfig(), }); From b9cf2148dee8783a290758415019820e4b3eff60 Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 28 May 2025 21:59:12 +0600 Subject: [PATCH 3/4] up --- lib/optimizely/index.tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/optimizely/index.tests.js b/lib/optimizely/index.tests.js index 75d631695..dc9d6f6ed 100644 --- a/lib/optimizely/index.tests.js +++ b/lib/optimizely/index.tests.js @@ -4407,7 +4407,7 @@ describe('lib/optimizely', function() { assert.deepEqual(user2.getUserId(), userId2); }); - it('should call the error handler for invalid user ID and return throw', function() { + it('should call the error handler for invalid user ID and throw', function() { const { optlyInstance, errorNotifier, createdLogger } = getOptlyInstance({ datafileObj: testData.getTestDecideProjectConfig(), }); From 8a62b66699db17c9deb332f5c51073fffa823747 Mon Sep 17 00:00:00 2001 From: Raju Ahmed Date: Wed, 28 May 2025 22:08:52 +0600 Subject: [PATCH 4/4] upd --- lib/optimizely/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/optimizely/index.ts b/lib/optimizely/index.ts index e4f3cd089..c84d6a4cb 100644 --- a/lib/optimizely/index.ts +++ b/lib/optimizely/index.ts @@ -1367,7 +1367,7 @@ export default class Optimizely extends BaseService implements Client { throw new Error(INVALID_IDENTIFIER); } - if (!this.validateInputs({ user_id: userIdentifier }, attributes)) { + if (!this.validateInputs({}, attributes)) { throw new Error(INVALID_ATTRIBUTES); }