codes: fix: marshal/unmarshal a Code to JSON fails (#2116)
Marshalling a Code to JSON and unmarshalling it failed with an "invalid code" error message. Code is of type uint32. It has no custom MarshalJson() implemented therefore it is marshalled into an JSON integer value. The UnmarshalJSON() function expected that the marshalled Code is a String type, unmarshalling failed. Check in UnmarshalJSON() if the value is an uint32 in the range of the defined Code values. If it is, unmarshal it. This commit also adds an Marshal/Unmarshal testcase.
This commit is contained in:
Родитель
590da37e2d
Коммит
b94ea975f3
|
@ -22,6 +22,7 @@ package codes // import "google.golang.org/grpc/codes"
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
|
||||
|
@ -143,6 +144,8 @@ const (
|
|||
// Unauthenticated indicates the request does not have valid
|
||||
// authentication credentials for the operation.
|
||||
Unauthenticated Code = 16
|
||||
|
||||
_maxCode = 17
|
||||
)
|
||||
|
||||
var strToCode = map[string]Code{
|
||||
|
@ -176,6 +179,16 @@ func (c *Code) UnmarshalJSON(b []byte) error {
|
|||
if c == nil {
|
||||
return fmt.Errorf("nil receiver passed to UnmarshalJSON")
|
||||
}
|
||||
|
||||
if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {
|
||||
if ci >= _maxCode {
|
||||
return fmt.Errorf("invalid code: %q", ci)
|
||||
}
|
||||
|
||||
*c = Code(ci)
|
||||
return nil
|
||||
}
|
||||
|
||||
if jc, ok := strToCode[string(b)]; ok {
|
||||
*c = jc
|
||||
return nil
|
||||
|
|
|
@ -62,3 +62,23 @@ func TestUnmarshalJSON_UnknownInput(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalJSON_MarshalUnmarshal(t *testing.T) {
|
||||
for i := 0; i < _maxCode; i++ {
|
||||
var cUnMarshaled Code
|
||||
c := Code(i)
|
||||
|
||||
cJSON, err := json.Marshal(c)
|
||||
if err != nil {
|
||||
t.Errorf("marshalling %q failed: %v", c, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(cJSON, &cUnMarshaled); err != nil {
|
||||
t.Errorf("unmarshalling code failed: %s", err)
|
||||
}
|
||||
|
||||
if c != cUnMarshaled {
|
||||
t.Errorf("code is %q after marshalling/unmarshalling, expected %q", cUnMarshaled, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче