You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
.ok_or(Error::Other(format!("Operation '{attr_name}' '{operator}' '[...]' failed to evaluate: '{attr_name}' not found in entity")))?;
86
-
for value in rule.values.iter()
87
-
{
88
-
let result = check_operator(attr_value, operator, value).context(format!("Operation '{attr_name}' '{operator}' '{value}' failed to evaluate."))?;
89
-
if result {returnOk(true)}
84
+
.get(attr_name);
85
+
if attr_value.is_none(){
86
+
returnOk(false)
87
+
}
88
+
let rule_result = match attr_value{
89
+
None => {
90
+
println!("Warning: Operation '{attr_name}' '{operator}' '[...]' failed to evaluate: '{attr_name}' not found in entity");
91
+
Ok(false)
92
+
},
93
+
Some(attr_value) => {
94
+
// FIXME: the following algorithm is too hard to read. Is it just me or do we need to simplify this?
95
+
// One of the values needs to match.
96
+
// Find a candidate (a candidate corresponds to a value which matches or which might match but the operator failed):
97
+
let candidate = rule.values.iter().find_map(|value| {
98
+
let result_for_value = check_operator(attr_value, operator, value).context(format!("Operation '{attr_name}' '{operator}' '{value}' failed to evaluate."));
99
+
match result_for_value{
100
+
Ok(true) => Some(Ok(())),
101
+
Ok(false) => None,
102
+
Err(e) => Some(Err(e))
103
+
}
104
+
});
105
+
// check if the candidate is good, or if the operator failed:
106
+
match candidate{
107
+
None => Ok(false),
108
+
Some(Ok(())) => Ok(true),
109
+
Some(Err(e)) => Err(e)
110
+
}
111
+
}
112
+
}?;
113
+
// All rules must match:
114
+
if !rule_result {
115
+
returnOk(false)
90
116
}
91
-
returnOk(false);
92
117
}
93
118
Ok(true)
94
119
}
@@ -212,27 +237,55 @@ pub mod tests {
212
237
}]
213
238
}
214
239
240
+
// SCENARIO - If the SDK user fail to pass the “attributes” for evaluation of featureflag which is segmented - we have considered that evaluation as “does not belong to any segment” and we serve the enabled_value.
241
+
// EXAMPLE - Assume two teams are using same featureflag. One team is interested only in enabled_value & disabled_value. This team doesn’t pass attributes for their evaluation. Other team wants to have overridden_value, as a result they update the featureflag by adding segment rules to it. This team passes attributes in their evaluation to get the overridden_value for matching segment, and enabled_value for non-matching segment.
// SCENARIO - The segment_id present in featureflag is invalid. In other words - the /config json dump has a featureflag, which has segment_rules. The segment_id in this segment_rules is invalid. Because this segment_id is not found in segments array.
258
+
// This is a very good question. Firstly, the our server-side API are strongly validating inputs and give the responses. We have unittests & integration tests that verifies the input & output of /config API. The response is always right. It is very much rare scenario where the API response has segment_id in featureflag object, that is not present is segments array.
259
+
// We can agree to return error and mark evaluation as failed.
// SCENARIO - evaluating an operator fails. Meaning, [for example] user has added a numeric value(int/float) in appconfig segment attribute, but in their application they pass the attribute with a boolean value.
0 commit comments