Skip to content

status/Details: unexpected code breaks after upgrading to v1.62.0 and higher #7679

@povsister

Description

@povsister

What version of gRPC are you using?

v1.62.0 and higher

What version of Go are you using (go version)?

go version go1.23.1 darwin/arm64

What operating system (Linux, Windows, …) and version?

Not related

What did you do?

After upgrading to v1.62.0, we have encountered serious problem on gRPC status detail extension: Our gRPC clients can not properly retrieve the customized err detail message from gRPC status.

After some investigation, we found it is caused by PR #6919
internal/status/status.go L157-L160
https://github.com/grpc/grpc-go/pull/6919/files#diff-d78e63ce979e5c67b7fa98a36052a2529e4232343046533343d9772c0cd52549R157-R160

The problem is: status.Details always return proto.MessageV1 before, but it now implicitly returns proto.MessageV2 because of changing protoV1.UnmarshalAny to any.UnmarshalNew.
This implicit behavior actually introduces compatibility issue, though gRPC itself doesn't make any guarantees on that.

Here is an example of our code extracting customized err details.
It unexpctly breaks after upgrading to v1.62.0 and higher.

// InternalErrMessage is a protobuf-defined and generated message.
// It is generated using protobuf v1  (aka: "github.com/golang/protobuf/proto")

func GetInternalErrMessage(gst *status.Status) *InternalErrMessage {
    for _, dt := range gst.Details() {
        // details may contain proto.Message or err.
        // For now, we only deal with proto.Message.
        // PROBLEM: this does not work with grpc-go >= v1.62.0.
        // The actual type of "dt" for now is "google.golang.org/protobuf/internal/impl/*messagelfaceWrapper" which
        // only implements proto.MessageV2 interface.
        if pbMsg, ok := dt.(proto.MessageV1); ok {
            // identify msg type and do type assertion
            if protoadapt.MessageV2Of(pbMsg).ProtoReflect().Descriptor().FullName() ==
                protoadapt.MessageV2Of(&InternalErrMessage{}).ProtoReflect().Descriptor().FullName() {
                    return pbMsg.(*InternalErrMessage)
            }
        }
    }
    // some fallback logic
}

What did you expect to see?

Our Code continues to work as expected after upgrading.

What did you see instead?

Code breaks because of implicit changes of return values from gRPC.

Metadata

Metadata

Assignees

Labels

Area: RPC FeaturesIncludes Compression, Encoding, Attributes/Metadata, Interceptors.Type: Bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions