diff --git a/manager/controlapi/service.go b/manager/controlapi/service.go index 06141d281b..a3ee2c7a4a 100644 --- a/manager/controlapi/service.go +++ b/manager/controlapi/service.go @@ -682,7 +682,10 @@ func (s *Server) CreateService(ctx context.Context, request *api.CreateServiceRe }) switch err { case store.ErrNameConflict: - return nil, status.Errorf(codes.AlreadyExists, "service %s already exists", request.Spec.Annotations.Name) + // Enhance the name-confict error to include the service name. The original + // `ErrNameConflict` error-message is included for backward-compatibility + // with older consumers of the API performing string-matching. + return nil, status.Errorf(codes.AlreadyExists, "%s: service %s already exists", err.Error(), request.Spec.Annotations.Name) case nil: return &api.CreateServiceResponse{Service: service}, nil default: diff --git a/manager/controlapi/service_test.go b/manager/controlapi/service_test.go index 9ea1192028..df34ffbaba 100644 --- a/manager/controlapi/service_test.go +++ b/manager/controlapi/service_test.go @@ -623,6 +623,10 @@ func TestCreateService(t *testing.T) { r, err = ts.Client.CreateService(context.Background(), &api.CreateServiceRequest{Spec: spec}) assert.Error(t, err) assert.Equal(t, codes.AlreadyExists, testutils.ErrorCode(err)) + + // Make sure the error contains "name conflicts with an existing object" for + // backward-compatibility with older clients doing string-matching... + assert.Contains(t, err.Error(), "name conflicts with an existing object") } func TestSecretValidation(t *testing.T) {