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:
Fabian Holler 2018-06-01 19:56:55 +02:00 коммит произвёл Menghan Li
Родитель 590da37e2d
Коммит b94ea975f3
2 изменённых файлов: 33 добавлений и 0 удалений

Просмотреть файл

@ -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)
}
}
}