Skip to content

Commit

Permalink
fix: preserve allocation evaluation details for ASSIGNMENT_ERROR
Browse files Browse the repository at this point in the history
  • Loading branch information
greghuels committed Jul 31, 2024
1 parent f76cae8 commit 89a5e6b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
12 changes: 1 addition & 11 deletions src/client/eppo-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ export default class EppoClient {
expectedVariationType,
);

if (!result.variation) {
if (!result.variation || result.flagEvaluationDetails.flagEvaluationCode !== 'MATCH') {
return {
eppoValue: defaultValue,
flagEvaluationDetails: result.flagEvaluationDetails,
Expand Down Expand Up @@ -784,16 +784,6 @@ export default class EppoClient {
result.flagKey = flagKey;
}

if (result?.variation && !checkValueTypeMatch(expectedVariationType, result.variation.value)) {
const { key: vKey, value: vValue } = result.variation;
const reason = `Variation (${vKey}) is configured for type ${expectedVariationType}, but is set to incompatible value (${vValue})`;
const flagEvaluationDetails = flagEvaluationDetailsBuilder.buildForNoneResult(
'ASSIGNMENT_ERROR',
reason,
);
return noneResult(flagKey, subjectKey, subjectAttributes, flagEvaluationDetails);
}

try {
if (result?.doLog) {
this.logAssignment(result);
Expand Down
43 changes: 34 additions & 9 deletions src/evaluator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { checkValueTypeMatch } from './client/eppo-client';
import {
AllocationEvaluation,
AllocationEvaluationCode,
IFlagEvaluationDetails,
FlagEvaluationDetailsBuilder,
FlagEvaluationCode,
} from './flag-evaluation-details-builder';
import {
Flag,
Expand Down Expand Up @@ -94,6 +96,14 @@ export class Evaluator {
split.shards.every((shard) => this.matchesShard(shard, subjectKey, flag.totalShards))
) {
const variation = flag.variations[split.variationKey];
const { flagEvaluationCode, flagEvaluationDescription } =
this.getMatchedEvaluationCodeAndDescription(
variation,
allocation,
split,
subjectKey,
expectedVariationType,
);
const flagEvaluationDetails = flagEvaluationDetailsBuilder
.setMatch(
i,
Expand All @@ -103,10 +113,7 @@ export class Evaluator {
unmatchedAllocations,
expectedVariationType,
)
.build(
'MATCH',
this.getMatchedEvaluationDetailsMessage(allocation, split, subjectKey),
);
.build(flagEvaluationCode, flagEvaluationDescription);
return {
flagKey: flag.key,
subjectKey,
Expand Down Expand Up @@ -143,23 +150,41 @@ export class Evaluator {
return shard.ranges.some((range) => isInShardRange(assignedShard, range));
}

private getMatchedEvaluationDetailsMessage = (
private getMatchedEvaluationCodeAndDescription = (
variation: Variation,
allocation: Allocation,
split: Split,
subjectKey: string,
): string => {
expectedVariationType: VariationType | undefined,
): { flagEvaluationCode: FlagEvaluationCode; flagEvaluationDescription: string } => {
if (!checkValueTypeMatch(expectedVariationType, variation.value)) {
const { key: vKey, value: vValue } = variation;
return {
flagEvaluationCode: 'ASSIGNMENT_ERROR',
flagEvaluationDescription: `Variation (${vKey}) is configured for type ${expectedVariationType}, but is set to incompatible value (${vValue})`,
};
}
const hasDefinedRules = !!allocation.rules?.length;
const isExperiment = allocation.splits.length > 1;
const isPartialRollout = split.shards.length > 1;
const isExperimentOrPartialRollout = isExperiment || isPartialRollout;

if (hasDefinedRules && isExperimentOrPartialRollout) {
return `Supplied attributes match rules defined in allocation "${allocation.key}" and ${subjectKey} belongs to the range of traffic assigned to "${split.variationKey}".`;
return {
flagEvaluationCode: 'MATCH',
flagEvaluationDescription: `Supplied attributes match rules defined in allocation "${allocation.key}" and ${subjectKey} belongs to the range of traffic assigned to "${split.variationKey}".`,
};
}
if (hasDefinedRules && !isExperimentOrPartialRollout) {
return `Supplied attributes match rules defined in allocation "${allocation.key}".`;
return {
flagEvaluationCode: 'MATCH',
flagEvaluationDescription: `Supplied attributes match rules defined in allocation "${allocation.key}".`,
};
}
return `${subjectKey} belongs to the range of traffic assigned to "${split.variationKey}" defined in allocation "${allocation.key}".`;
return {
flagEvaluationCode: 'MATCH',
flagEvaluationDescription: `${subjectKey} belongs to the range of traffic assigned to "${split.variationKey}" defined in allocation "${allocation.key}".`,
};
};
}

Expand Down

0 comments on commit 89a5e6b

Please sign in to comment.