couchbase报错: You must encode a string in a string or interface

在调用接口时couchbase服务报错。

原来的代码:

func (impl *Impl) GetResourceByID(ctx context.Context, metadata *core.Meta) (*types.Struct, error) {
	impl.logger.Debugw("searching for item", "item", metadata)
	umarshaler := jsonpb.Unmarshaler{}
	var buffer json.RawMessage
	_, err := impl.resourceBucket.Get(metadata.ID, &buffer)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get event: %s", err.Error())
	}
	result := &types.Struct{}
	err = umarshaler.Unmarshal(bytes.NewReader(buffer), result)
	if err != nil {
		return nil, status.Errorf(codes.Internal, "failed to get task: %s", err.Error())
	}
	return result, nil
}

在追踪代码时到https://github.com/couchbase/gocb/blob/master/transcoding.go:

// Decode applies the default Couchbase transcoding behaviour to decode into a Go type.
func (t *DefaultTranscoder) Decode(bytes []byte, flags uint32, out interface{}) error {
	valueType, compression := gocbcore.DecodeCommonFlags(flags)

	// Make sure compression is disabled
	if compression != gocbcore.NoCompression {
		return clientError{"Unexpected value compression"}
	}

	// Normal types of decoding
	if valueType == gocbcore.BinaryType {
		switch typedOut := out.(type) {
		case *[]byte:
			*typedOut = bytes
			return nil
		case *interface{}:
			*typedOut = bytes
			return nil
		default:
			return clientError{"You must encode binary in a byte array or interface"}
		}
	} else if valueType == gocbcore.StringType {
		switch typedOut := out.(type) {
		case *string:
			*typedOut = string(bytes)
			return nil
		case *interface{}:
			*typedOut = string(bytes)
			return nil
		default:
			return clientError{"You must encode a string in a string or interface"}
		}
	} else if valueType == gocbcore.JsonType {
		err := t.serializer.Deserialize(bytes, &out)
		if err != nil {
			return err
		}
		return nil
	}

	return clientError{"Unexpected flags value"}
}

即在调用接口“GetResourceByID”传值,Unmarshal第一个参数NewReader中buffer应为string,则将buffer的类型改为“string”。

修改如下,并自行import strings:

func (impl *Impl) GetResourceByID(ctx context.Context, metadata *core.Meta) (*types.Struct, error) {
var buffer string
...
err = umarshaler.Unmarshal(strings.NewReader(buffer), result)
...
}

又或者:

func (impl *Impl) GetResourceByID(ctx context.Context, metadata *core.Meta) (*types.Struct, error) {
var buffer interface{}
...
err = umarshaler.Unmarshal(strings.NewReader(buffer.(string)), result)
...
}

本人是这样修改的。

你可能感兴趣的:(Linux,虚拟机)