Skip to content

Commit ca1ec03

Browse files
committed
refactor: improve error formatting
1 parent c64f592 commit ca1ec03

23 files changed

+61
-63
lines changed

api/config/extension.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
infrastructure "github.com/ninech/apis/infrastructure/v1alpha1"
1111
"github.com/ninech/nctl/internal/cli"
12+
"github.com/ninech/nctl/internal/format"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1314
"k8s.io/apimachinery/pkg/runtime"
1415
"k8s.io/client-go/tools/clientcmd"
@@ -21,10 +22,8 @@ const (
2122
NctlExtensionContext = "nctl"
2223
)
2324

24-
var (
25-
// ErrExtensionNotFound describes a missing extension in the kubeconfig
26-
ErrExtensionNotFound extensionError = "nctl config not found"
27-
)
25+
// ErrExtensionNotFound describes a missing extension in the kubeconfig
26+
var ErrExtensionNotFound extensionError = "nctl config not found"
2827

2928
type extensionError string
3029

@@ -208,10 +207,7 @@ func contextNotFoundError[T any](contextName string, contexts map[string]T) erro
208207
return cli.ErrorWithContext(fmt.Errorf("could not find context %q in kubeconfig", contextName)).
209208
WithExitCode(cli.ExitUsageError).
210209
WithAvailable(available...).
211-
WithSuggestions(
212-
"List available contexts: kubectl config get-contexts",
213-
"Login to the API: nctl auth login",
214-
)
210+
WithSuggestions("Login to the API: " + format.Command().Login())
215211
}
216212

217213
// clusterNotFoundError returns an error with available clusters listed.

api/util/bucket_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package util
22

33
import (
4+
"strings"
45
"testing"
56

67
storage "github.com/ninech/apis/storage/v1alpha1"
@@ -298,7 +299,7 @@ func TestParseCORSLooseWithMask(t *testing.T) {
298299

299300
if tt.wantErr != "" {
300301
assert.Error(t, err)
301-
assert.Contains(t, err.Error(), tt.wantErr)
302+
assert.Contains(t, strings.ToLower(err.Error()), strings.ToLower(tt.wantErr))
302303
return
303304
}
304305
assert.NoError(t, err)

auth/set_project.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (s *SetProjectCmd) Run(ctx context.Context, client *api.Client) error {
4242
org,
4343
)
4444
if err := trySwitchOrg(ctx, client, s.Name); err != nil {
45-
return fmt.Errorf("failed to switch organization: %w", err)
45+
return err
4646
}
4747

4848
org, err = client.Organization()

auth/set_project_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package auth
33
import (
44
"context"
55
"errors"
6+
"strings"
67
"testing"
78

89
management "github.com/ninech/apis/management/v1alpha1"
@@ -116,7 +117,7 @@ func TestOrgFromProjectAPIErrors(t *testing.T) {
116117
is.NoError(err)
117118

118119
_, err = orgFromProject(t.Context(), apiClient, "test-prod")
119-
is.ErrorContains(err, tc.wantErrContain)
120+
is.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.wantErrContain))
120121
})
121122
}
122123
}

create/serviceconnection.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,23 @@ import (
1212
"sigs.k8s.io/controller-runtime/pkg/client"
1313

1414
"github.com/alecthomas/kong"
15+
apps "github.com/ninech/apis/apps/v1alpha1"
16+
infrastructure "github.com/ninech/apis/infrastructure/v1alpha1"
1517
meta "github.com/ninech/apis/meta/v1alpha1"
1618
networking "github.com/ninech/apis/networking/v1alpha1"
19+
storage "github.com/ninech/apis/storage/v1alpha1"
1720
"github.com/ninech/nctl/api"
1821
"github.com/ninech/nctl/internal/cli"
1922
)
2023

24+
// These might be replaced to fetch compatible resources from the schema.
25+
var (
26+
// allowedSources are the allowed source kinds for a service connection.
27+
allowedSources = []string{infrastructure.KubernetesClusterKind, apps.ApplicationKind}
28+
// allowedDestinations are the allowed destination kinds for a service connection.
29+
allowedDestinations = []string{storage.KeyValueStoreKind, storage.MySQLKind, storage.PostgresKind, storage.MySQLDatabaseKind}
30+
)
31+
2132
type serviceConnectionCmd struct {
2233
resourceCmd
2334
Source TypedReference `placeholder:"kind/name" help:"Source of the connection in the form kind/name. Allowed source kinds are: ${allowed_sources}." required:""`
@@ -200,32 +211,26 @@ func groupVersionKindFromKind(kind string) (schema.GroupVersionKind, error) {
200211
return schema.GroupVersionKind{}, fmt.Errorf("error creating scheme: %w", err)
201212
}
202213

203-
var availableKinds []string
204214
for gvk := range scheme.AllKnownTypes() {
205215
if strings.EqualFold(kind, gvk.Kind) {
206216
return gvk, nil
207217
}
208-
// Collect non-list kinds for error message
209-
if !strings.HasSuffix(gvk.Kind, "List") && gvk.Kind != "" {
210-
availableKinds = append(availableKinds, strings.ToLower(gvk.Kind))
211-
}
212218
}
213219

214220
return schema.GroupVersionKind{}, cli.ErrorWithContext(fmt.Errorf("kind %q is invalid", kind)).
215221
WithExitCode(cli.ExitUsageError).
216-
WithAvailable(availableKinds...).
217222
WithSuggestions(
218-
"Valid source kinds: kubernetescluster, application",
219-
"Valid destination kinds: keyvaluestore, mysql, postgres, mysqldatabase, postgresdatabase",
223+
"Valid source kinds: "+strings.Join(allowedSources, ", "),
224+
"Valid destination kinds: "+strings.Join(allowedDestinations, ", "),
220225
)
221226
}
222227

223228
// ServiceConnectionKongVars returns all variables which are used in the ServiceConnection
224229
// create command
225230
func ServiceConnectionKongVars() kong.Vars {
226231
result := make(kong.Vars)
227-
result["allowed_sources"] = "kubernetescluster, application"
228-
result["allowed_destinations"] = "keyvaluestore, mysql, postgres, mysqldatabase, postgresdatabase"
232+
result["allowed_sources"] = strings.Join(allowedSources, ", ")
233+
result["allowed_destinations"] = strings.Join(allowedDestinations, ", ")
229234
result["label_selector_placeholder"] = "'key1=value1,key2=value2,key3 in (value3)'"
230235
result["label_selector_usage"] = "Selector (label query) to filter on, supports '=', '==', '!=', 'in', 'notin'. Matching objects must satisfy all of the specified label constraints."
231236
result["label_selector_requirements"] = "Can only be set when the source is a KubernetesCluster."

get/all_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"os"
7+
"strings"
78
"testing"
89

910
apps "github.com/ninech/apis/apps/v1alpha1"
@@ -322,7 +323,7 @@ dev pear Release apps.nine.ch
322323
if testCase.errorExpected {
323324
require.Error(t, err)
324325
for _, s := range testCase.errorContains {
325-
assert.Contains(t, err.Error(), s)
326+
assert.Contains(t, strings.ToLower(err.Error()), strings.ToLower(s))
326327
}
327328
return
328329
}

get/bucket_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package get
33
import (
44
"bytes"
55
"context"
6+
"strings"
67
"testing"
78
"time"
89

@@ -258,7 +259,7 @@ func TestBucketGet(t *testing.T) {
258259
if tt.wantErr {
259260
require.Error(t, err)
260261
for _, s := range tt.wantContain {
261-
assert.Contains(t, err.Error(), s, "missing expected substring %q in error:\n%s", s, err)
262+
assert.Contains(t, strings.ToLower(err.Error()), strings.ToLower(s), "missing expected substring %q in error:\n%s", s, err)
262263
}
263264
return
264265
}

get/bucketuser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func TestBucketUser(t *testing.T) {
136136
}
137137
if tt.wantErr {
138138
for _, substr := range tt.wantContain {
139-
if !strings.Contains(err.Error(), substr) {
139+
if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(substr)) {
140140
t.Errorf("bucketUserCmd.Run() error did not contain %q, err = %v", substr, err)
141141
}
142142
}

get/cloudvm_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func TestCloudVM(t *testing.T) {
135135
}
136136
if tt.wantErr {
137137
for _, substr := range tt.wantContain {
138-
if !strings.Contains(err.Error(), substr) {
138+
if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(substr)) {
139139
t.Errorf("cloudVMCmd.Run() error did not contain %q, err = %v", substr, err)
140140
}
141141
}

get/database_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ func TestDatabase(t *testing.T) {
170170
}
171171
if tt.wantErr {
172172
for _, substr := range tt.wantContain {
173-
if !strings.Contains(err.Error(), substr) {
173+
if !strings.Contains(strings.ToLower(err.Error()), strings.ToLower(substr)) {
174174
t.Errorf("postgresDatabaseCmd.Run() error did not contain %q, err = %v", substr, err)
175175
}
176176
}

0 commit comments

Comments
 (0)