/// <summary> /// Adds the result of a flag evaluation. /// </summary> /// <param name="flagKey">the flag key</param> /// <param name="result">the evaluation result</param> /// <returns></returns> public FeatureFlagsStateBuilder AddFlag(string flagKey, EvaluationDetail <LdValue> result) { return(AddFlag(flagKey, result?.Value.InnerValue, result?.VariationIndex, result?.Reason, 0, false, null)); }
internal EvalResult(EvaluationDetail <JToken> result, IList <FeatureRequestEvent> events) : this() { Result = result; PrerequisiteEvents = events; }
private EvaluationDetail <JToken> Evaluate(string featureKey, User user, JToken defaultValue, JTokenType?expectedType, EventFactory eventFactory) { if (!Initialized()) { if (_featureStore.Initialized()) { Log.Warn("Flag evaluation before client initialized; using last known values from feature store"); } else { Log.Warn("Flag evaluation before client initialized; feature store unavailable, returning default value"); return(new EvaluationDetail <JToken>(defaultValue, null, new EvaluationReason.Error(EvaluationErrorKind.CLIENT_NOT_READY))); } } FeatureFlag featureFlag = null; try { featureFlag = _featureStore.Get(VersionedDataKind.Features, featureKey); if (featureFlag == null) { Log.InfoFormat("Unknown feature flag {0}; returning default value", featureKey); _eventProcessor.SendEvent(eventFactory.NewUnknownFeatureRequestEvent(featureKey, user, defaultValue, EvaluationErrorKind.FLAG_NOT_FOUND)); return(new EvaluationDetail <JToken>(defaultValue, null, new EvaluationReason.Error(EvaluationErrorKind.FLAG_NOT_FOUND))); } if (user == null || user.Key == null) { Log.Warn("Feature flag evaluation called with null user or null user key. Returning default"); _eventProcessor.SendEvent(eventFactory.NewDefaultFeatureRequestEvent(featureFlag, user, defaultValue, EvaluationErrorKind.USER_NOT_SPECIFIED)); return(new EvaluationDetail <JToken>(defaultValue, null, new EvaluationReason.Error(EvaluationErrorKind.USER_NOT_SPECIFIED))); } FeatureFlag.EvalResult evalResult = featureFlag.Evaluate(user, _featureStore, eventFactory); if (!IsOffline()) { foreach (var prereqEvent in evalResult.PrerequisiteEvents) { _eventProcessor.SendEvent(prereqEvent); } } var detail = evalResult.Result; if (detail.VariationIndex == null) { detail = new EvaluationDetail <JToken>(defaultValue, null, detail.Reason); } if (detail.Value != null && !CheckResultType(expectedType, detail.Value)) { Log.ErrorFormat("Expected type: {0} but got {1} when evaluating FeatureFlag: {2}. Returning default", expectedType, detail.Value.GetType(), featureKey); _eventProcessor.SendEvent(eventFactory.NewDefaultFeatureRequestEvent(featureFlag, user, defaultValue, EvaluationErrorKind.WRONG_TYPE)); return(new EvaluationDetail <JToken>(defaultValue, null, new EvaluationReason.Error(EvaluationErrorKind.WRONG_TYPE))); } _eventProcessor.SendEvent(eventFactory.NewFeatureRequestEvent(featureFlag, user, detail, defaultValue)); return(detail); } catch (Exception e) { Log.ErrorFormat("Encountered exception in LaunchDarkly client: {0} when evaluating feature key: {1} for user key: {2}", Util.ExceptionMessage(e), featureKey, user.Key); Log.Debug(e.ToString(), e); var detail = new EvaluationDetail <JToken>(defaultValue, null, new EvaluationReason.Error(EvaluationErrorKind.EXCEPTION)); if (featureFlag == null) { _eventProcessor.SendEvent(eventFactory.NewUnknownFeatureRequestEvent(featureKey, user, defaultValue, EvaluationErrorKind.EXCEPTION)); } else { _eventProcessor.SendEvent(eventFactory.NewFeatureRequestEvent(featureFlag, user, detail, defaultValue)); } return(detail); } }