From 2296535dac74e3d7e924eb9e8ea0379d174b61a2 Mon Sep 17 00:00:00 2001 From: Daniel Baptista Dias Date: Wed, 25 Oct 2023 18:57:58 -0300 Subject: [PATCH] fix: added support to unauthorized error (#3292) --- cli/cmd/middleware.go | 18 ++++++++++++++- cli/pkg/resourcemanager/client.go | 38 ++++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/cli/cmd/middleware.go b/cli/cmd/middleware.go index d065d2da5b..08aa4c4200 100644 --- a/cli/cmd/middleware.go +++ b/cli/cmd/middleware.go @@ -1,9 +1,12 @@ package cmd import ( + "errors" "fmt" "os" + "github.com/kubeshop/tracetest/cli/pkg/resourcemanager" + "github.com/spf13/cobra" ) @@ -27,6 +30,8 @@ func WithResultHandler(runFn RunFn) CobraRunFn { } func OnError(err error) { + errorMessage := handleErrorMessage(err) + fmt.Fprintf(os.Stderr, ` Version %s @@ -34,10 +39,21 @@ Version An error ocurred when executing the command %s -`, versionText, err.Error()) +`, versionText, errorMessage) ExitCLI(1) } +func handleErrorMessage(err error) string { + var requestError resourcemanager.RequestError + hasRequestError := errors.As(err, &requestError) + + if !hasRequestError || requestError.Code != 401 { + return err.Error() + } + + return fmt.Sprintf("user is not authenticated on %s", cliConfig.Endpoint) +} + func WithParamsHandler(validators ...Validator) MiddlewareWrapper { return func(runFn RunFn) RunFn { return func(cmd *cobra.Command, args []string) (string, error) { diff --git a/cli/pkg/resourcemanager/client.go b/cli/pkg/resourcemanager/client.go index f789b6e293..0f3ba2c900 100644 --- a/cli/pkg/resourcemanager/client.go +++ b/cli/pkg/resourcemanager/client.go @@ -128,22 +128,27 @@ func (c Client) resourceType() string { return caser.String(c.resourceName) } -var ErrNotFound = requestError{ +var ErrNotFound = RequestError{ Code: http.StatusNotFound, Message: "Resource not found", } -type requestError struct { +type RequestError struct { Code int `json:"code"` Message string `json:"error"` } -func (e requestError) Error() string { +type alternateRequestError struct { + Status int `json:"status"` + Detail string `json:"detail"` +} + +func (e RequestError) Error() string { return e.Message } -func (e requestError) Is(target error) bool { - t, ok := target.(requestError) +func (e RequestError) Is(target error) bool { + t, ok := target.(RequestError) return ok && t.Code == e.Code } @@ -159,16 +164,33 @@ func parseRequestError(resp *http.Response, format Format) error { } if len(body) == 0 { - return requestError{ + return RequestError{ Code: resp.StatusCode, Message: resp.Status, } } - var reqErr requestError + var reqErr RequestError err = format.Unmarshal(body, &reqErr) if err != nil { return fmt.Errorf("cannot parse response body: %w", err) } - return reqErr + emptyRequestError := reqErr.Code == 0 && reqErr.Message == "" + if !emptyRequestError { + // Success, parsed error message + return reqErr + } + + // Fallback, try to parse message in other format + + var alternateReqError alternateRequestError + err = format.Unmarshal(body, &alternateReqError) + if err != nil { + return fmt.Errorf("cannot parse response body: %w", err) + } + + return RequestError{ + Code: alternateReqError.Status, + Message: alternateReqError.Detail, + } }