diff --git a/internal/util/funcutil/func.go b/internal/util/funcutil/func.go index 70b3855e9f74513de39b8487a97865136ebe3968..b8a6cbd972a89c386a81c228f51fdf972e38f8d9 100644 --- a/internal/util/funcutil/func.go +++ b/internal/util/funcutil/func.go @@ -357,9 +357,14 @@ func ReadBinary(endian binary.ByteOrder, bs []byte, receiver interface{}) error // IsGrpcErr checks whether err is instance of grpc status error. func IsGrpcErr(err error) bool { - if err == nil { - return false + for { + if err == nil { + return false + } + _, ok := grpcStatus.FromError(err) + if ok { + return true + } + err = errors.Unwrap(err) } - _, ok := grpcStatus.FromError(err) - return ok } diff --git a/internal/util/funcutil/func_test.go b/internal/util/funcutil/func_test.go index d5c542dc0c5faebb4b2b18524ca8596ee78c0bfa..35d6c49e71445bf405de4f3d1d56cea9e56e1992 100644 --- a/internal/util/funcutil/func_test.go +++ b/internal/util/funcutil/func_test.go @@ -467,26 +467,37 @@ func Test_ReadBinary(t *testing.T) { } func TestIsGrpcErr(t *testing.T) { - var err1 error - assert.False(t, IsGrpcErr(err1)) - - err1 = errors.New("error") - assert.False(t, IsGrpcErr(err1)) - - bgCtx := context.Background() - ctx1, cancel1 := context.WithCancel(bgCtx) - cancel1() - assert.False(t, IsGrpcErr(ctx1.Err())) - - timeout := 20 * time.Millisecond - ctx1, cancel1 = context.WithTimeout(bgCtx, timeout) - time.Sleep(timeout * 2) - assert.False(t, IsGrpcErr(ctx1.Err())) - cancel1() - - err1 = grpcStatus.Error(grpcCodes.Canceled, "test") - assert.True(t, IsGrpcErr(err1)) - - err1 = grpcStatus.Error(grpcCodes.Unavailable, "test") - assert.True(t, IsGrpcErr(err1)) + t.Run("nil error", func(t *testing.T) { + var err error + assert.False(t, IsGrpcErr(err)) + }) + + t.Run("normal errors new", func(t *testing.T) { + err := errors.New("error") + assert.False(t, IsGrpcErr(err)) + }) + + t.Run("context cancel", func(t *testing.T) { + assert.False(t, IsGrpcErr(context.Canceled)) + }) + + t.Run("context timeout", func(t *testing.T) { + assert.False(t, IsGrpcErr(context.DeadlineExceeded)) + }) + + t.Run("grpc canceled", func(t *testing.T) { + err := grpcStatus.Error(grpcCodes.Canceled, "test") + assert.True(t, IsGrpcErr(err)) + }) + + t.Run("grpc unavailable", func(t *testing.T) { + err := grpcStatus.Error(grpcCodes.Unavailable, "test") + assert.True(t, IsGrpcErr(err)) + }) + + t.Run("wrapped grpc error", func(t *testing.T) { + err := grpcStatus.Error(grpcCodes.Unavailable, "test") + errWrap := fmt.Errorf("wrap grpc error %w", err) + assert.True(t, IsGrpcErr(errWrap)) + }) }