• HOME
  • INTEGRATIONS
  • SDK
  • API DOCS
No results for ""
EXPAND ALL
CLOSE
launchdarkly.com

EDIT ON GITHUB

Evaluation reasons

Read time: 2 minutes
Last edited: Feb 20, 2020

Overview

This topic explains how to use LaunchDarkly to determine why a user receives a given flag variation. It can be useful to have this information when you're diagnosing problems or doing analysis of the impact of different flags.

You can access this information programmatically from your SDK or from Data Export events. To learn more about Data Export, read Data Export.

Accessing flag variation information programmatically

For each of the SDK methods that you call to evaluate a feature flag, there is a corresponding detail method.

This method returns three pieces of information:

  • The computed flag variation, which what you get when you only evaluated the flag
  • The variation index, which is a zero-based integer indicating which variation was selected. For example, if the flag's possible variations are A, B, and C, in that order, and the current variation is C, the variation index would be 2. This value is useful for tabulation, although in some cases, it may be absent. To learn more, read Error conditions.
  • A reason object, which contains information about why that variation was selected. This data structure is described below.

An example call in our Go SDK is depicted below:

1value, detail, err := client.BoolVariationDetail("flag-key", myUser, false)
2
3// or StringVariationDetail for a string-valued flag, etc.
4
5index := detail.VariationIndex // may be nil
6reason := detail.Reason // will always be present

Understanding the reason data

In strongly typed languages, the reason object is composed of specific classes. In other languages, it is a hash, such as a dictionary or object.

The JSON representation is the same in every language, so we will describe the reason object here as if it were a JSON object.

The reason object's only required property is kind. This describes the general reason that LaunchDarkly selected this variation. The possible values for kind are enums in the strongly typed languages and strings in other languages.

These values are:

Value nameDescription
OFFThe flag is on, but the user did not match any targets or rules, so it returned the value that appears on the dashboard under "Default rule." The "default rule" is not the same thing as the default value discussed in "Error conditions".
FALLTHROUGHThe flag is off and therefore returned its configured off value. This value appears on the dashboard next to "If targeting is off, serve: ".
TARGET_MATCHThe user key was specifically targeted for this flag in the "Target individual users" section.
RULE_MATCHThe user who encountered the flag matched one of the flag's rules. In this case, the reason object also has these properties: ruleIndex, which is the positional index of the matched rule (0 for the first rule), and ruleId, which is the rule's unique identifier, which stays the same even if you rearrange the order of the rules.
PREREQUISITE_FAILEDThe flag had at least one prerequisite flag that either was off or did not return the desired variation. Because of this, the flag returned its "off" value. In this case, the reason object also has this property: prerequisiteKey: The key of the prerequisite flag that failed.
ERRORThe flag could not be evaluated, so the default value was returned.

Here is an example of how you could access the details of a reason object in some of LaunchDarkly's SDKs:

1func PrintReason(reason ldclient.EvaluationReason) {
2 switch r := reason.(type) {
3 case EvaluationReasonOff:
4 fmt.Println("it's off")
5
6 case EvaluationReasonFallthrough:
7 fmt.Println("fell through")
8
9 case EvaluationReasonTargetMatch:
10 fmt.Println("targeted")
11
12 case EvaluationReasonRuleMatch:
13 fmt.Printf("matched rule %d/%s\n", r.RuleIndex, r.RuleID)
14
15 case EvaluationReasonPrerequisiteFailed:
16 fmt.Printf("prereq failed: %s\n", r.PrerequisiteKey)
17
18 case EvaluationReasonError:
19 fmt.Printf("error: %s\n", r.ErrorKind)
20
21 }
22 // or, if all you want is a simple descriptive string:
23 fmt.Println(reason)
24
25}

Error conditions

If the kind is ERROR, it means that the SDK was unable to select any of the flag's variations. This is an abnormal occurrence.

In this case, the returned flag value is default value that you specified in your code, which is the last parameter of the method you called to evaluate the flag, rather than any value that you specified on your dashboard. In addition, the variation index will be null/nil.

When there is an error, the reason object also has an errorKind property which will be one of the following:

Property NameDescription
CLIENT_NOT_READYThe client is not able to establish a connection to LaunchDarkly yet. If there is a persistent feature store, the store does not yet contain flag data.
FLAG_NOT_FOUNDThe flag key did not match any known flag.
USER_NOT_SPECIFIEDThe user object or user key was not provided.
MALFORMED_FLAGThere was an internal inconsistency in the flag data. For example, a rule specified a nonexistent variation. This is an unusual condition that might require assistance from LaunchDarkly's Support team.
WRONG_TYPEAn unexpected error stopped flag evaluation. This could happen if you are using a persistent feature store and the database stops working. When this happens, the SDK always prints the specific error to the log.
EXCEPTIONThe application code requested the flag value with a different data type than it actually is. For example, the code asked for a boolean when the flag type is actually a string. This can only happen in strongly typed languages, such as Go, Java, and C#.

Understanding how Data Export events display

Calling any of the variation detail methods not only make extra information available to your code, it also causes the SDK to include it in analytics events. You can see this information if you use the event debugger or Data Export.

To learn more, read Data Export.

The JSON representation of the reason data will be included in the feature evaluation event as an extra property called reason.

For instance, a debug event might look like this:

1{
2 "type": "debug",
3 "creationDate": 1548195712000,
4 "key": "my-flag-key",
5 "userKey": "test@example.com",
6 "version": 1000,
7 "variation": 0,
8 "value": true,
9 "default": false,
10 "reason": {
11 "kind": "TARGET_MATCH"
12 }
13}