-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
consolidate default value type comparisons into local bucketing code #247
base: remove-indirection
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,12 @@ | |
|
||
import ( | ||
"errors" | ||
"reflect" | ||
"time" | ||
|
||
"github.com/devcyclehq/go-server-sdk/v2/api" | ||
"github.com/devcyclehq/go-server-sdk/v2/util" | ||
"github.com/devcyclehq/go-server-sdk/v2/variable-utils" | ||
) | ||
|
||
// Max value of an unsigned 32-bit integer, which is what murmurhash returns | ||
|
@@ -212,7 +214,9 @@ | |
}, nil | ||
} | ||
|
||
func VariableForUser(sdkKey string, user api.PopulatedUser, variableKey string, expectedVariableType string, eventQueue *EventQueue, clientCustomData map[string]interface{}) (variableType string, variableValue any, err error) { | ||
func VariableForUser(sdkKey string, user api.PopulatedUser, variableKey string, defaultValue interface{}, eventQueue *EventQueue, clientCustomData map[string]interface{}) (variableType string, variableValue any, err error) { | ||
expectedVariableType, err := variable_utils.VariableTypeFromValue(variableKey, defaultValue, true) | ||
|
||
variableType, variableValue, featureId, variationId, err := generateBucketedVariableForUser(sdkKey, user, variableKey, clientCustomData) | ||
if err != nil { | ||
eventErr := eventQueue.QueueVariableDefaultedEvent(variableKey, BucketResultErrorToDefaultReason(err)) | ||
|
@@ -222,9 +226,17 @@ | |
return "", nil, err | ||
} | ||
|
||
if !isVariableTypeValid(variableType, expectedVariableType) && expectedVariableType != "" { | ||
typeFieldMismatch := !isVariableTypeValid(variableType, expectedVariableType) && expectedVariableType != "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This kind of one liner is discouraged - and should be done in the if statement to make it more transparent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i found it so much harder to read the if statement condition when i inlined it all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you really want to make it oneliner'd - move the explicit variable call checks first to make it more visible. |
||
valueFieldMismatch := defaultValue != nil && !variable_utils.CompareTypes(variableValue, defaultValue) | ||
|
||
if typeFieldMismatch || valueFieldMismatch { | ||
err = ErrInvalidVariableType | ||
eventErr := eventQueue.QueueVariableDefaultedEvent(variableKey, BucketResultErrorToDefaultReason(err)) | ||
util.Warnf("Type mismatch for variable %s. Expected type %s, got %s", | ||
variableKey, | ||
reflect.TypeOf(defaultValue).String(), | ||
reflect.TypeOf(variableValue).String(), | ||
) | ||
if eventErr != nil { | ||
util.Warnf("Failed to queue variable defaulted event: %s", eventErr) | ||
} | ||
|
@@ -303,6 +315,8 @@ | |
return "USER_NOT_TARGETED" | ||
case ErrInvalidVariableType: | ||
return "INVALID_VARIABLE_TYPE" | ||
case variable_utils.ErrInvalidDefaultValue: | ||
return "INVALID_DEFAULT_VALUE" | ||
Comment on lines
+326
to
+327
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should make these accessible constants still. |
||
default: | ||
return "Unknown" | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package variable_utils | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could add the default reasons here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. feels like they should go in the same place as the error definitions that cause them, which is all in the bucketing package There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. really it doesn't matter where - they can be imported from anywhere |
||
var ErrInvalidDefaultValue = errors.New("the default value for variable is not of type Boolean, Number, String, or JSON") | ||
|
||
func ConvertDefaultValueType(value interface{}) interface{} { | ||
switch value := value.(type) { | ||
case int: | ||
return float64(value) | ||
case int8: | ||
return float64(value) | ||
case int16: | ||
return float64(value) | ||
case int32: | ||
return float64(value) | ||
case int64: | ||
return float64(value) | ||
case uint: | ||
return float64(value) | ||
case uint8: | ||
return float64(value) | ||
case uint16: | ||
return float64(value) | ||
case uint32: | ||
return float64(value) | ||
case uint64: | ||
return float64(value) | ||
case float32: | ||
return float64(value) | ||
default: | ||
return value | ||
} | ||
} | ||
|
||
func VariableTypeFromValue(key string, value interface{}, allowNil bool) (varType string, err error) { | ||
switch value.(type) { | ||
case float64: | ||
return "Number", nil | ||
case string: | ||
return "String", nil | ||
case bool: | ||
return "Boolean", nil | ||
case map[string]any: | ||
return "JSON", nil | ||
case nil: | ||
if allowNil { | ||
return "", nil | ||
} | ||
} | ||
|
||
return "", fmt.Errorf("%w: %s", ErrInvalidDefaultValue, key) | ||
} | ||
|
||
func CompareTypes(value1 interface{}, value2 interface{}) bool { | ||
return reflect.TypeOf(value1) == reflect.TypeOf(value2) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check the error result here