diff --git a/internal/querycoordv2/services.go b/internal/querycoordv2/services.go index 58f5668835..2f43dc17ff 100644 --- a/internal/querycoordv2/services.go +++ b/internal/querycoordv2/services.go @@ -809,13 +809,23 @@ func (s *Server) GetReplicas(ctx context.Context, req *milvuspb.GetReplicasReque } for _, replica := range replicas { - info, err := s.fillReplicaInfo(replica, req.GetWithShardNodes()) - if err != nil { - msg := "failed to get replica info" + msg := "failed to get replica info" + if len(replica.GetNodes()) == 0 { + err := merr.WrapErrNoAvailableNodeInReplica(replica.ID) log.Warn(msg, zap.Int64("replica", replica.GetID()), zap.Error(err)) resp.Status = utils.WrapStatus(commonpb.ErrorCode_MetaFailed, msg, err) + break + } + + info, err := s.fillReplicaInfo(replica, req.GetWithShardNodes()) + if err != nil { + log.Warn(msg, + zap.Int64("replica", replica.GetID()), + zap.Error(err)) + resp.Status = utils.WrapStatus(commonpb.ErrorCode_MetaFailed, msg, err) + break } resp.Replicas = append(resp.Replicas, info) } diff --git a/internal/querycoordv2/services_test.go b/internal/querycoordv2/services_test.go index baef3119c7..2bc9528020 100644 --- a/internal/querycoordv2/services_test.go +++ b/internal/querycoordv2/services_test.go @@ -1404,6 +1404,24 @@ func (suite *ServiceSuite) TestGetReplicas() { suite.Equal(resp.GetStatus().GetCode(), merr.Code(merr.ErrServiceNotReady)) } +func (suite *ServiceSuite) TestGetReplicasFailed() { + suite.loadAll() + ctx := context.Background() + server := suite.server + + suite.meta.ReplicaManager.Put(utils.CreateTestReplica(100001, 100000, []int64{})) + suite.meta.ReplicaManager.Put(utils.CreateTestReplica(100002, 100000, []int64{1})) + + req := &milvuspb.GetReplicasRequest{ + CollectionID: 100000, + WithShardNodes: true, + } + resp, err := server.GetReplicas(ctx, req) + suite.NoError(err) + suite.Equal(commonpb.ErrorCode_MetaFailed, resp.GetStatus().GetErrorCode()) + suite.EqualValues(resp.GetStatus().GetReason(), "failed to get replica info, err=replica=100001: no available node in replica") +} + func (suite *ServiceSuite) TestCheckHealth() { ctx := context.Background() server := suite.server diff --git a/pkg/util/merr/errors.go b/pkg/util/merr/errors.go index cb8b621faa..6d1b08b836 100644 --- a/pkg/util/merr/errors.go +++ b/pkg/util/merr/errors.go @@ -67,7 +67,8 @@ var ( ErrResourceGroupNotFound = newMilvusError("resource group not found", 300, false) // Replica related - ErrReplicaNotFound = newMilvusError("replica not found", 400, false) + ErrReplicaNotFound = newMilvusError("replica not found", 400, false) + ErrNoAvailableNodeInReplica = newMilvusError("no available node in replica", 401, false) // Channel related ErrChannelNotFound = newMilvusError("channel not found", 500, false) diff --git a/pkg/util/merr/utils.go b/pkg/util/merr/utils.go index 3a48a03c8c..7f9e5c74f6 100644 --- a/pkg/util/merr/utils.go +++ b/pkg/util/merr/utils.go @@ -220,6 +220,14 @@ func WrapErrReplicaNotFound(id int64, msg ...string) error { return err } +func WrapErrNoAvailableNodeInReplica(id int64, msg ...string) error { + err := wrapWithField(ErrNoAvailableNodeInReplica, "replica", id) + if len(msg) > 0 { + err = errors.Wrap(err, strings.Join(msg, "; ")) + } + return err +} + // Channel related func WrapErrChannelNotFound(name string, msg ...string) error { err := wrapWithField(ErrChannelNotFound, "channel", name)