diff --git a/cliv2/cmd/cliv2/main.go b/cliv2/cmd/cliv2/main.go index 85708910600..f7913351f07 100644 --- a/cliv2/cmd/cliv2/main.go +++ b/cliv2/cmd/cliv2/main.go @@ -37,6 +37,8 @@ import ( "github.com/snyk/snyk-iac-capture/pkg/capture" snykls "github.com/snyk/snyk-ls/ls_extension" + "github.com/snyk/go-application-framework/pkg/ui" + "github.com/snyk/cli/cliv2/internal/cliv2" "github.com/snyk/cli/cliv2/internal/constants" cli_errors "github.com/snyk/cli/cliv2/internal/errors" @@ -369,7 +371,7 @@ func handleError(err error) HandleError { return resultError } -func displayError(err error, output io.Writer, config configuration.Configuration) { +func displayError(err error, userInterface ui.UserInterface, config configuration.Configuration) { if err != nil { var exitCode *cli_errors.ErrorWithExitCode _, isExitError := err.(*exec.ExitError) @@ -386,13 +388,14 @@ func displayError(err error, output io.Writer, config configuration.Configuratio } jsonErrorBuffer, _ := json.MarshalIndent(jsonError, "", " ") - fmt.Fprintln(output, string(jsonErrorBuffer)) + userInterface.Output(string(jsonErrorBuffer)) } else { if errors.Is(err, context.DeadlineExceeded) { - fmt.Fprintln(output, "command timed out") - } else { - fmt.Fprintln(output, err) + err = fmt.Errorf("command timed out") } + + uiError := userInterface.OutputError(err) + globalLogger.Err(uiError).Msg("ui failed show error") } } } @@ -492,7 +495,7 @@ func MainWithErrorCode() int { cliAnalytics.AddError(err) } - displayError(err, os.Stdout, globalConfiguration) + displayError(err, globalEngine.GetUserInterface(), globalConfiguration) exitCode := cliv2.DeriveExitCode(err) globalLogger.Printf("Exiting with %d", exitCode) diff --git a/cliv2/cmd/cliv2/main_test.go b/cliv2/cmd/cliv2/main_test.go index 28517492f1b..59a0b4e1f43 100644 --- a/cliv2/cmd/cliv2/main_test.go +++ b/cliv2/cmd/cliv2/main_test.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "encoding/json" "errors" "fmt" @@ -10,11 +9,13 @@ import ( "testing" "time" + "github.com/golang/mock/gomock" "github.com/rs/zerolog" "github.com/snyk/go-application-framework/pkg/configuration" localworkflows "github.com/snyk/go-application-framework/pkg/local_workflows" "github.com/snyk/go-application-framework/pkg/local_workflows/content_type" "github.com/snyk/go-application-framework/pkg/local_workflows/json_schemas" + "github.com/snyk/go-application-framework/pkg/mocks" "github.com/snyk/go-application-framework/pkg/workflow" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -380,13 +381,15 @@ func Test_setTimeout(t *testing.T) { } func Test_displayError(t *testing.T) { + mockController := gomock.NewController(t) + userInterface := mocks.NewMockUserInterface(mockController) + t.Run("prints out generic error messages", func(t *testing.T) { - var b bytes.Buffer - config := configuration.NewInMemory() err := errors.New("test error") - displayError(err, &b, config) + userInterface.EXPECT().OutputError(err).Times(1) - assert.Equal(t, "test error\n", b.String()) + config := configuration.NewInMemory() + displayError(err, userInterface, config) }) scenarios := []struct { @@ -405,22 +408,18 @@ func Test_displayError(t *testing.T) { for _, scenario := range scenarios { t.Run(fmt.Sprintf("%s does not display anything", scenario.name), func(t *testing.T) { - var b bytes.Buffer config := configuration.NewInMemory() err := scenario.err - displayError(err, &b, config) - - assert.Equal(t, "", b.String()) + displayError(err, userInterface, config) }) } t.Run("prints messages of error wrapping exec.ExitError", func(t *testing.T) { - var b bytes.Buffer - config := configuration.NewInMemory() err := &wrErr{wraps: &exec.ExitError{}} - displayError(err, &b, config) + userInterface.EXPECT().OutputError(err).Times(1) - assert.Equal(t, "something went wrong\n", b.String()) + config := configuration.NewInMemory() + displayError(err, userInterface, config) }) } diff --git a/cliv2/go.mod b/cliv2/go.mod index 9b91deb4399..dfa46f62363 100644 --- a/cliv2/go.mod +++ b/cliv2/go.mod @@ -6,6 +6,7 @@ require ( github.com/elazarl/goproxy v0.0.0-20231031074852-3ec07828be7a github.com/elazarl/goproxy/ext v0.0.0-20230808193330-2592e75ae04a github.com/gofrs/flock v0.8.1 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.6.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.32.0 @@ -13,7 +14,7 @@ require ( github.com/snyk/cli-extension-iac-rules v0.0.0-20240422133948-ae17a4306672 github.com/snyk/cli-extension-sbom v0.0.0-20240426130148-b83c2ebc75c4 github.com/snyk/container-cli v0.0.0-20240322120441-6d9b9482f9b1 - github.com/snyk/go-application-framework v0.0.0-20240513111557-0f09a5c36e29 + github.com/snyk/go-application-framework v0.0.0-20240514092950-6354c46f27a0 github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65 github.com/snyk/snyk-iac-capture v0.6.5 github.com/snyk/snyk-ls v0.0.0-20240510163626-041f744c3180 @@ -75,7 +76,6 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 // indirect github.com/google/go-cmp v0.6.0 // indirect @@ -150,6 +150,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/snyk/code-client-go v1.5.5 // indirect + github.com/snyk/error-catalog-golang-public v0.0.0-20240425141803-2516e42296c3 // indirect github.com/snyk/policy-engine v0.30.11 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/sourcegraph/go-lsp v0.0.0-20240223163137-f80c5dd31dfd // indirect diff --git a/cliv2/go.sum b/cliv2/go.sum index 718c3728299..724724a4610 100644 --- a/cliv2/go.sum +++ b/cliv2/go.sum @@ -729,8 +729,10 @@ github.com/snyk/code-client-go v1.5.5 h1:YHgNvh17jVTuSvPVMoeNuDn40z1qb99EfXva/sS github.com/snyk/code-client-go v1.5.5/go.mod h1:Kkr7pQc8ItsBZSYd6A1S4r4VHO6HNyTWZsqi18sAtwQ= github.com/snyk/container-cli v0.0.0-20240322120441-6d9b9482f9b1 h1:9RKY9NdX5DrJAoVXDP0JiqrXT+4Nb9NH8pjEcA0NsLA= github.com/snyk/container-cli v0.0.0-20240322120441-6d9b9482f9b1/go.mod h1:38w+dcAQp9eG3P5t2eNS9eG0reut10AeJjLv5lJ5lpM= -github.com/snyk/go-application-framework v0.0.0-20240513111557-0f09a5c36e29 h1:eYR9egt6c5IufIpAmmK7pRzkTFoQrjofRcMUVQNLJqQ= -github.com/snyk/go-application-framework v0.0.0-20240513111557-0f09a5c36e29/go.mod h1:9KumW8tE7XNww31fhIvMoTIqpW+LdUHlhzrIV3X3PL8= +github.com/snyk/error-catalog-golang-public v0.0.0-20240425141803-2516e42296c3 h1:ZUaY5LIVGQ0GScf1SsaqvUxaiGbBKgBBLsQUgB4Zx5o= +github.com/snyk/error-catalog-golang-public v0.0.0-20240425141803-2516e42296c3/go.mod h1:Ytttq7Pw4vOCu9NtRQaOeDU2dhBYUyNBe6kX4+nIIQ4= +github.com/snyk/go-application-framework v0.0.0-20240514092950-6354c46f27a0 h1:jjf3wfGVL3eQdHMU5cHXBWdi6BPBk981JA+mAaKWATo= +github.com/snyk/go-application-framework v0.0.0-20240514092950-6354c46f27a0/go.mod h1:5gvF6i1sqmk1oN21ZbX/EDaEyQtPMfK1pbYCwtS+Fvw= github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65 h1:CEQuYv0Go6MEyRCD3YjLYM2u3Oxkx8GpCpFBd4rUTUk= github.com/snyk/go-httpauth v0.0.0-20240307114523-1f5ea3f55c65/go.mod h1:88KbbvGYlmLgee4OcQ19yr0bNpXpOr2kciOthaSzCAg= github.com/snyk/policy-engine v0.30.11 h1:wUy5LMar2vccMbNM62MSBRdjAQAhAbIm7aNXXO+g2tk=