I use jsonpb to marshal the protobuf object to json string. Use EnumsAsInts: false so that the enum field is written as a string in json.
But when I use jsonpb to unmarshall it back to protobuf i am getting the following error:
Received unexpected error "unknown value \"ERROR\" for enum logging.LogLevel"
But when I set EnumsAsInts: true and the enum is written as a int, the unmarshal works.
The unmarshal should also be able to unmarshal enum from string, right?
Hmm... the following testcases show that it can unmarshal string to enum value --
https://github.com/golang/protobuf/blob/master/jsonpb/jsonpb_test.go#L507:L511
Can you provide the proto definition and the JSON string input? Simplifying it only to the error case would be good.
Thanks.
@cybrcodr
Here is my protobuf definition
enum LogLevel {
FATAL = 0;
ERROR = 1;
WARN = 2;
INFO = 3;
}
message ServiceLog {
LogLevel level = 1;
string message = 2;
}
And here is my testing code:
import (
"testing"
"github.com/golang/protobuf/jsonpb"
"github.com/stretchr/testify/assert"
"strings"
)
func TestUnmarshal(t *testing.T) {
logJson := `{"level":"ERROR","message":"hello world"}`
um := jsonpb.Unmarshaler{}
log2 := ServiceLog{}
err := um.Unmarshal(strings.NewReader(logJson), &log2)
assert.NoError(t, err)
}
I tried the protobuf unit-test and I can successfully run it. But not sure why my own tests are failing though.
Sorry for the false alarm. I think I vendored a older version of protobuf that caused this. Feel free to close this
Sorry for the late response. No worries. I tried it out just to verify and your case works for me.
log2 := ServiceLog{}
err := um.Unmarshal(strings.NewReader(logJson), &log2)
log2 := &ServiceLog{}
err := um.Unmarshal(strings.NewReader(logJson), log2)
Hi, I checked on 2 cases. First code is that @guodongx mentioned, Second code is just that I checked with pointer.
2 cases result are different.
First case is showing LogLevel by "FATAL" for default.
but second case is losing default value and not include LogLevel parameter.
In the real development, we are using pointer for return value. So I am losing default enum values.
What is the solution? or is this Protobuf bug?
my workaround: register manullay if protobuf shall not be initialized at proper phase
func init() {
proto.RegisterEnum("MY_ENUM, MY_ENUM_name, MY_ENUM_value)
}
try to use package "github.com/golang/protobuf/jsonpb" not gogo version
Most helpful comment
try to use package "github.com/golang/protobuf/jsonpb" not gogo version