Skip to content
This repository has been archived by the owner on Oct 9, 2023. It is now read-only.

Commit

Permalink
Handle grpc error explicitly (#602)
Browse files Browse the repository at this point in the history
Signed-off-by: Iaroslav Ciupin <[email protected]>
  • Loading branch information
iaroslav-ciupin authored Aug 11, 2023
1 parent 38a233d commit d492640
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 23 deletions.
38 changes: 24 additions & 14 deletions pkg/rpc/adminservice/util/transformers.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
package util

import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/flyteorg/flyteadmin/pkg/common"
"github.com/flyteorg/flyteadmin/pkg/errors"

"google.golang.org/grpc/codes"
)

// Transforms errors to grpc-compatible error types and optionally truncates it if necessary.
// TransformAndRecordError transforms errors to grpc-compatible error types and optionally truncates it if necessary.
func TransformAndRecordError(err error, metrics *RequestMetrics) error {
var errorMessage = err.Error()
concatenateErrMessage := false
if len(errorMessage) > common.MaxResponseStatusBytes {
errorMessage = err.Error()[:common.MaxResponseStatusBytes]
concatenateErrMessage = true
errMsg := err.Error()
shouldTruncate := false
if len(errMsg) > common.MaxResponseStatusBytes {
errMsg = errMsg[:common.MaxResponseStatusBytes]
shouldTruncate = true
}
if flyteAdminError, ok := err.(errors.FlyteAdminError); !ok {
err = errors.NewFlyteAdminError(codes.Internal, errorMessage)
} else if concatenateErrMessage {
err = errors.NewFlyteAdminError(flyteAdminError.Code(), errorMessage)

adminErr, isAdminErr := err.(errors.FlyteAdminError)
grpcStatus, isStatus := status.FromError(err)
switch {
case isAdminErr:
if shouldTruncate {
adminErr = errors.NewFlyteAdminError(adminErr.Code(), errMsg)
}
case isStatus:
adminErr = errors.NewFlyteAdminError(grpcStatus.Code(), errMsg)
default:
adminErr = errors.NewFlyteAdminError(codes.Internal, errMsg)
}
metrics.Record(err.(errors.FlyteAdminError).Code())
return err

metrics.Record(adminErr.Code())
return adminErr
}
36 changes: 27 additions & 9 deletions pkg/rpc/adminservice/util/transformers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,69 @@ package util
import (
"context"
"errors"
"strings"
"testing"

"github.com/flyteorg/flyteadmin/pkg/common"

adminErrors "github.com/flyteorg/flyteadmin/pkg/errors"
mockScope "github.com/flyteorg/flytestdlib/promutils"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

"github.com/flyteorg/flyteadmin/pkg/common"
adminErrors "github.com/flyteorg/flyteadmin/pkg/errors"
)

var testRequestMetrics = NewRequestMetrics(mockScope.NewTestScope(), "foo")

func TestTransformError_FlyteAdminError(t *testing.T) {
invalidArgError := adminErrors.NewFlyteAdminError(codes.InvalidArgument, "invalid arg")

transformedError := TransformAndRecordError(invalidArgError, &testRequestMetrics)

transormerStatus, ok := status.FromError(transformedError)
assert.True(t, ok)
assert.Equal(t, codes.InvalidArgument, transormerStatus.Code())
}

func TestTransformError_FlyteAdminErrorWithDetails(t *testing.T) {
terminalStateError := adminErrors.NewAlreadyInTerminalStateError(context.Background(), "terminal state", "curPhase")

transformedError := TransformAndRecordError(terminalStateError, &testRequestMetrics)

transormerStatus, ok := status.FromError(transformedError)
assert.True(t, ok)
assert.Equal(t, codes.FailedPrecondition, transormerStatus.Code())
assert.Equal(t, 1, len(transormerStatus.Details()))
}

func TestTransformError_GRPCError(t *testing.T) {
err := status.Error(codes.InvalidArgument, strings.Repeat("X", common.MaxResponseStatusBytes+1))

transformedError := TransformAndRecordError(err, &testRequestMetrics)

transormerStatus, ok := status.FromError(transformedError)
assert.True(t, ok)
assert.Equal(t, codes.InvalidArgument, transormerStatus.Code())
assert.Len(t, transormerStatus.Message(), common.MaxResponseStatusBytes)
}

func TestTransformError_BasicError(t *testing.T) {
err := errors.New("some error")

transformedError := TransformAndRecordError(err, &testRequestMetrics)

transormerStatus, ok := status.FromError(transformedError)
assert.True(t, ok)
assert.Equal(t, codes.Internal, transormerStatus.Code())
}

func TestTruncateErrorMessage(t *testing.T) {
errorMessage := make([]byte, common.MaxResponseStatusBytes+1)
for i := 0; i <= common.MaxResponseStatusBytes; i++ {
errorMessage[i] = byte('a')
}
err := adminErrors.NewFlyteAdminError(codes.InvalidArgument, strings.Repeat("X", common.MaxResponseStatusBytes+1))

err := adminErrors.NewFlyteAdminError(codes.InvalidArgument, string(errorMessage))
transformedError := TransformAndRecordError(err, &testRequestMetrics)
assert.Len(t, transformedError.Error(), common.MaxResponseStatusBytes)

transormerStatus, ok := status.FromError(transformedError)
assert.True(t, ok)
assert.Equal(t, codes.InvalidArgument, transormerStatus.Code())
assert.Len(t, transormerStatus.Message(), common.MaxResponseStatusBytes)
}

0 comments on commit d492640

Please sign in to comment.