diff --git a/status/status.go b/status/status.go index 7577625b0c4..53910fb7c90 100644 --- a/status/status.go +++ b/status/status.go @@ -78,7 +78,8 @@ func FromProto(s *spb.Status) *Status { // // - If err was produced by this package or implements the method `GRPCStatus() // *Status`, or if err wraps a type satisfying this, the appropriate Status is -// returned. +// returned. For wrapped errors, the message returned contains the entire +// err.Error() text and not just the wrapped status. // // - If err is nil, a Status is returned with codes.OK and no message. // @@ -89,9 +90,15 @@ func FromError(err error) (s *Status, ok bool) { if err == nil { return nil, true } - var se interface{ GRPCStatus() *Status } - if errors.As(err, &se) { - return se.GRPCStatus(), true + type grpcstatus interface{ GRPCStatus() *Status } + if gs, ok := err.(grpcstatus); ok { + return gs.GRPCStatus(), true + } + var gs grpcstatus + if errors.As(err, &gs) { + p := gs.GRPCStatus().Proto() + p.Message = err.Error() + return status.FromProto(p), true } return New(codes.Unknown, err.Error()), false } diff --git a/status/status_test.go b/status/status_test.go index 244cb8151fd..b0bb3fcb67c 100644 --- a/status/status_test.go +++ b/status/status_test.go @@ -197,7 +197,7 @@ func (s) TestFromErrorWrapped(t *testing.T) { const code, message = codes.Internal, "test description" err := fmt.Errorf("wrapped error: %w", Error(code, message)) s, ok := FromError(err) - if !ok || s.Code() != code || s.Message() != message || s.Err() == nil { + if !ok || s.Code() != code || s.Message() != err.Error() || s.Err() == nil { t.Fatalf("FromError(%v) = %v, %v; want , true", err, s, ok, code, message) } } @@ -206,7 +206,7 @@ func (s) TestFromErrorImplementsInterfaceWrapped(t *testing.T) { const code, message = codes.Internal, "test description" err := fmt.Errorf("wrapped error: %w", customError{Code: code, Message: message}) s, ok := FromError(err) - if !ok || s.Code() != code || s.Message() != message || s.Err() == nil { + if !ok || s.Code() != code || s.Message() != err.Error() || s.Err() == nil { t.Fatalf("FromError(%v) = %v, %v; want , true", err, s, ok, code, message) } }