diff --git a/status/status.go b/status/status.go index 53910fb7c901..d35ae60cd057 100644 --- a/status/status.go +++ b/status/status.go @@ -92,10 +92,20 @@ func FromError(err error) (s *Status, ok bool) { } type grpcstatus interface{ GRPCStatus() *Status } if gs, ok := err.(grpcstatus); ok { + if gs.GRPCStatus() == nil { + // Error has a status of OK. There is no sensible behavior for this, so map it to Unknown and discard the + // status. + return New(codes.Unknown, err.Error()), false + } return gs.GRPCStatus(), true } var gs grpcstatus if errors.As(err, &gs) { + if gs.GRPCStatus() == nil { + // Error wraps an error that has an OK status. There is no sensible behavior for this, so map it to Unknown + // and discard the status. + return New(codes.Unknown, err.Error()), false + } p := gs.GRPCStatus().Proto() p.Message = err.Error() return status.FromProto(p), true diff --git a/status/status_test.go b/status/status_test.go index b0bb3fcb67cc..d5d257e5c0a2 100644 --- a/status/status_test.go +++ b/status/status_test.go @@ -202,6 +202,33 @@ func (s) TestFromErrorWrapped(t *testing.T) { } } +type customErrorNilStatus struct { +} + +func (c customErrorNilStatus) Error() string { + return fmt.Sprintf("test") +} + +func (c customErrorNilStatus) GRPCStatus() *Status { + return nil +} + +func (s) TestFromErrorImplementsInterfaceReturnsOKStatus(t *testing.T) { + err := customErrorNilStatus{} + s, ok := FromError(err) + if ok || s.Code() != codes.Unknown || s.Message() != err.Error() { + t.Fatalf("FromError(%v) = %v, %v; want , true", err, s, ok, codes.Unknown, err.Error()) + } +} + +func (s) TestFromErrorImplementsInterfaceReturnsOKStatusWrapped(t *testing.T) { + err := fmt.Errorf("wrapping: %w", customErrorNilStatus{}) + s, ok := FromError(err) + if ok || s.Code() != codes.Unknown || s.Message() != err.Error() { + t.Fatalf("FromError(%v) = %v, %v; want , true", err, s, ok, codes.Unknown, err.Error()) + } +} + func (s) TestFromErrorImplementsInterfaceWrapped(t *testing.T) { const code, message = codes.Internal, "test description" err := fmt.Errorf("wrapped error: %w", customError{Code: code, Message: message})