Skip to content

Commit

Permalink
fix(feature flags) : Local evaluation : guard for null values when co…
Browse files Browse the repository at this point in the history
…mparing person Properties (#249)

Guard for null values when comparing person Properties
Add a `NULL_VALUES_ALLOWED_OPERATORS` array of operators that allow `NULL/UNDEFINED` values which is just is_not right now . Any other operator will fail if the overrideValue is null or undefined

Co-authored-by: Dylan Martin <[email protected]>
  • Loading branch information
Phanatic and dmarticus authored Aug 20, 2024
1 parent 256ebdb commit 092e786
Show file tree
Hide file tree
Showing 2 changed files with 286 additions and 146 deletions.
24 changes: 19 additions & 5 deletions posthog-node/src/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import fetch from './fetch'
// eslint-disable-next-line
const LONG_SCALE = 0xfffffffffffffff

const NULL_VALUES_ALLOWED_OPERATORS = ['is_not']
class ClientError extends Error {
constructor(message: string) {
super()
Expand Down Expand Up @@ -305,7 +306,11 @@ class FeatureFlagsPoller {
properties: Record<string, string>
): boolean {
const rolloutPercentage = condition.rollout_percentage

const warnFunction = (msg: string): void => {
if (this.debugMode) {
console.warn(msg)
}
}
if ((condition.properties || []).length > 0) {
for (const prop of condition.properties) {
const propertyType = prop.type
Expand All @@ -314,7 +319,7 @@ class FeatureFlagsPoller {
if (propertyType === 'cohort') {
matches = matchCohort(prop, properties, this.cohorts, this.debugMode)
} else {
matches = matchProperty(prop, properties)
matches = matchProperty(prop, properties, warnFunction)
}

if (!matches) {
Expand Down Expand Up @@ -460,9 +465,9 @@ function _hash(key: string, distinctId: string, salt: string = ''): number {
}

function matchProperty(
property: FeatureFlagCondition['properties'][number],
propertyValues: Record<string, any>
): boolean {
property: FeatureFlagCondition["properties"][number],
propertyValues: Record<string, any>
, warnFunction?: (msg: string) => void): boolean {
const key = property.key
const value = property.value
const operator = property.operator || 'exact'
Expand All @@ -474,6 +479,15 @@ function matchProperty(
}

const overrideValue = propertyValues[key]
if (overrideValue == null && !NULL_VALUES_ALLOWED_OPERATORS.includes(operator)) {
// if the value is null, just fail the feature flag comparison
// this isn't an InconclusiveMatchError because the property value was provided.
if (warnFunction) {
warnFunction(`Property ${key} cannot have a value of null/undefined with the ${operator} operator`)
}

return false
}

function computeExactMatch(value: any, overrideValue: any): boolean {
if (Array.isArray(value)) {
Expand Down
Loading

0 comments on commit 092e786

Please sign in to comment.