@@ -2,15 +2,17 @@ package lduser
22
33import  (
44	"encoding/json" 
5- 	"errors " 
5+ 	"reflect " 
66
77	"gopkg.in/launchdarkly/go-sdk-common.v2/jsonstream" 
88	"gopkg.in/launchdarkly/go-sdk-common.v2/ldvalue" 
99)
1010
11- var  (
12- 	errMissingKey  =  errors .New ("" )
13- )
11+ type  missingKeyError  struct {}
12+ 
13+ func  (e  missingKeyError ) Error () string  {
14+ 	return  "User must have a key property" 
15+ }
1416
1517// ErrMissingKey returns the standard error value that is used if you try to unmarshal a user from JSON 
1618// and the "key" property is either absent or null. This is distinguished from other kinds of unmarshaling 
2022// LaunchDarkly does allow a user to have an empty string ("") as a key in some cases, but this is 
2123// discouraged since analytics events will not work properly without unique user keys. 
2224func  ErrMissingKey () error  {
23- 	return  errMissingKey 
25+ 	return  missingKeyError {} 
2426}
2527
2628// This temporary struct allows us to do JSON unmarshalling as efficiently as possible while not requiring 
@@ -76,13 +78,23 @@ func (u User) MarshalJSON() ([]byte, error) {
7678// Any property that is either completely omitted or has a null value is ignored and left in an unset 
7779// state, except for "key". All users must have a key (even if it is ""), so an omitted or null "key" 
7880// property causes the error ErrMissingKey(). 
81+ // 
82+ // Trying to unmarshal any non-struct value, including a JSON null, into a User will return a 
83+ // json.UnmarshalTypeError. If you want to unmarshal optional user data that might be null, use *User 
84+ // instead of User. 
7985func  (u  * User ) UnmarshalJSON (data  []byte ) error  {
86+ 	// Special handling here for a null value - json.Unmarshal will normally treat a null exactly like 
87+ 	// "{}" when unmarshaling a struct. We don't want that, because it will produce a misleading 
88+ 	// "missing key" error further down. Instead, just treat it as an invalid type. 
89+ 	if  string (data ) ==  "null"  {
90+ 		return  & json.UnmarshalTypeError {Value : string (data ), Type : reflect .TypeOf (u )}
91+ 	}
8092	var  ufs  userForDeserialization 
8193	if  err  :=  json .Unmarshal (data , & ufs ); err  !=  nil  {
8294		return  err 
8395	}
8496	if  ! ufs .Key .IsDefined () {
85- 		return  errMissingKey 
97+ 		return  ErrMissingKey () 
8698	}
8799	* u  =  User {
88100		key :       ufs .Key .StringValue (),
0 commit comments