From 55898677522b9d3f1528d18cdbc9d008e93e8dff Mon Sep 17 00:00:00 2001 From: curzola pierre Date: Fri, 2 Oct 2020 15:54:17 +0200 Subject: [PATCH 1/6] Add informative error --- apps/scale.go | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/apps/scale.go b/apps/scale.go index 8d5fb9790..502b6603a 100644 --- a/apps/scale.go +++ b/apps/scale.go @@ -8,10 +8,12 @@ import ( "strings" "github.com/Scalingo/cli/config" - "github.com/Scalingo/go-scalingo/debug" "github.com/Scalingo/cli/io" "github.com/Scalingo/cli/utils" "github.com/Scalingo/go-scalingo" + "github.com/Scalingo/go-scalingo/debug" + "github.com/Scalingo/go-scalingo/http" + "github.com/Scalingo/go-utils/errors" "gopkg.in/errgo.v1" ) @@ -107,6 +109,11 @@ func Scale(app string, sync bool, types []string) error { res, err := c.AppsScale(app, scaleParams) if err != nil { if !utils.IsPaymentRequiredAndFreeTrialExceededError(err) { + reqestFailedError, ok := errors.ErrgoRoot(err).(*http.RequestFailedError) + if !ok || reqestFailedError.Code == 422 { + return formatContainerTypesError(c, app) + } + return errgo.Mask(err) } // If error is Payment Required and user tries to exceed its free trial @@ -140,6 +147,41 @@ func Scale(app string, sync bool, types []string) error { return nil } +func formatContainerTypesError(c *scalingo.Client, app string) error { + containerTypes, _ := c.AppsPs(app) + var containerTypesName string + + if len(containerTypes) == 0 { + return errgo.New("You haven't container types yet.\nPlease refer to the documentation to deploy your application.") + } + + for _, containerType := range containerTypes { + if containerTypesName == "" { + containerTypesName = "'" + containerType.Name + "'" + continue + } + containerTypesName = containerTypesName + ", '" + containerType.Name + "'" + } + + errMessage := `Containers type not found. + +Your available container ` + if len(containerTypes) > 1 { + errMessage += "types are" + } else { + errMessage += "type is" + } + errMessage += ": " + containerTypesName + `. + +Example of usage: +scalingo --app my-app scale web:2 worker:1 +scalingo --app my-app scale web:1:XL +scalingo --app my-app scale web:+1 worker:-1 + +Use 'scalingo scale --help' for more information` + return errgo.New(errMessage) +} + func autoscaleDisableMessage(typesWithAutoscaler []string) string { if len(typesWithAutoscaler) <= 0 { return "" From ce878285d2212705a8deb360280e6421e54c6b9b Mon Sep 17 00:00:00 2001 From: curzola pierre Date: Fri, 2 Oct 2020 15:57:14 +0200 Subject: [PATCH 2/6] add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb1178643..02f7eb368 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### To be Released +* Add informative error in case of container type error + [602](https://github.com/Scalingo/cli/pull/602) + ### 1.19.3 * Add support for new log drain/addon log drain events From b93a996a1387195e009a1d16d2c537b857951cad Mon Sep 17 00:00:00 2001 From: curzola pierre Date: Fri, 2 Oct 2020 17:34:08 +0200 Subject: [PATCH 3/6] more detail changelog entry. Clearer condition and error messages --- CHANGELOG.md | 2 +- apps/scale.go | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02f7eb368..76edafba4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### To be Released -* Add informative error in case of container type error +* Add informative error in case of container type error when scaling an application [602](https://github.com/Scalingo/cli/pull/602) ### 1.19.3 diff --git a/apps/scale.go b/apps/scale.go index 502b6603a..f3220d069 100644 --- a/apps/scale.go +++ b/apps/scale.go @@ -109,8 +109,10 @@ func Scale(app string, sync bool, types []string) error { res, err := c.AppsScale(app, scaleParams) if err != nil { if !utils.IsPaymentRequiredAndFreeTrialExceededError(err) { - reqestFailedError, ok := errors.ErrgoRoot(err).(*http.RequestFailedError) - if !ok || reqestFailedError.Code == 422 { + reqestFailedError, _ := errors.ErrgoRoot(err).(*http.RequestFailedError) + + // In case of unprocessable, format and return an clear error + if reqestFailedError.Code == 422 { return formatContainerTypesError(c, app) } @@ -148,13 +150,15 @@ func Scale(app string, sync bool, types []string) error { } func formatContainerTypesError(c *scalingo.Client, app string) error { - containerTypes, _ := c.AppsPs(app) - var containerTypesName string - + containerTypes, err := c.AppsPs(app) + if err != nil { + return errgo.Notef(err, "Fail to get container types.") + } if len(containerTypes) == 0 { - return errgo.New("You haven't container types yet.\nPlease refer to the documentation to deploy your application.") + return errgo.New("You have no container type yet.\nPlease refer to the documentation to deploy your application.") } + var containerTypesName string for _, containerType := range containerTypes { if containerTypesName == "" { containerTypesName = "'" + containerType.Name + "'" From 58cd70396da0e90fe7966eef9c2c431e7d468840 Mon Sep 17 00:00:00 2001 From: curzola pierre Date: Fri, 2 Oct 2020 17:46:56 +0200 Subject: [PATCH 4/6] add more context to the primary error --- apps/scale.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/scale.go b/apps/scale.go index f3220d069..b9de5f237 100644 --- a/apps/scale.go +++ b/apps/scale.go @@ -113,7 +113,7 @@ func Scale(app string, sync bool, types []string) error { // In case of unprocessable, format and return an clear error if reqestFailedError.Code == 422 { - return formatContainerTypesError(c, app) + return formatContainerTypesError(c, app, reqestFailedError) } return errgo.Mask(err) @@ -149,7 +149,7 @@ func Scale(app string, sync bool, types []string) error { return nil } -func formatContainerTypesError(c *scalingo.Client, app string) error { +func formatContainerTypesError(c *scalingo.Client, app string, reqestFailedError *http.RequestFailedError) error { containerTypes, err := c.AppsPs(app) if err != nil { return errgo.Notef(err, "Fail to get container types.") @@ -167,7 +167,7 @@ func formatContainerTypesError(c *scalingo.Client, app string) error { containerTypesName = containerTypesName + ", '" + containerType.Name + "'" } - errMessage := `Containers type not found. + errMessage := reqestFailedError.APIError.Error() + ` Your available container ` if len(containerTypes) > 1 { From 204380c25985baf39e43ddb01d79537bada9afb6 Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Mon, 19 Oct 2020 18:08:18 +0200 Subject: [PATCH 5/6] If we fail to display a smart error message, fallback to the API one --- apps/scale.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/scale.go b/apps/scale.go index b9de5f237..0b3077439 100644 --- a/apps/scale.go +++ b/apps/scale.go @@ -109,9 +109,12 @@ func Scale(app string, sync bool, types []string) error { res, err := c.AppsScale(app, scaleParams) if err != nil { if !utils.IsPaymentRequiredAndFreeTrialExceededError(err) { - reqestFailedError, _ := errors.ErrgoRoot(err).(*http.RequestFailedError) + reqestFailedError, ok := errors.ErrgoRoot(err).(*http.RequestFailedError) + if !ok { + return errgo.Mask(err) + } - // In case of unprocessable, format and return an clear error + // In case of unprocessable, format and return a clear error if reqestFailedError.Code == 422 { return formatContainerTypesError(c, app, reqestFailedError) } @@ -149,11 +152,13 @@ func Scale(app string, sync bool, types []string) error { return nil } -func formatContainerTypesError(c *scalingo.Client, app string, reqestFailedError *http.RequestFailedError) error { +func formatContainerTypesError(c *scalingo.Client, app string, requestFailedError *http.RequestFailedError) error { containerTypes, err := c.AppsPs(app) if err != nil { - return errgo.Notef(err, "Fail to get container types.") + debug.Println(fmt.Sprintf("Failed to get container types: %s", err.Error())) + return requestFailedError } + if len(containerTypes) == 0 { return errgo.New("You have no container type yet.\nPlease refer to the documentation to deploy your application.") } @@ -167,7 +172,7 @@ func formatContainerTypesError(c *scalingo.Client, app string, reqestFailedError containerTypesName = containerTypesName + ", '" + containerType.Name + "'" } - errMessage := reqestFailedError.APIError.Error() + ` + errMessage := requestFailedError.APIError.Error() + ` Your available container ` if len(containerTypes) > 1 { From fd3f44530d52c3fd4f5f1a9b9e74a29a0b05e177 Mon Sep 17 00:00:00 2001 From: Jonathan Hurter Date: Fri, 23 Oct 2020 16:55:15 +0200 Subject: [PATCH 6/6] Update apps/scale.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Étienne M. --- apps/scale.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/scale.go b/apps/scale.go index 0b3077439..ceb87a0c7 100644 --- a/apps/scale.go +++ b/apps/scale.go @@ -111,7 +111,7 @@ func Scale(app string, sync bool, types []string) error { if !utils.IsPaymentRequiredAndFreeTrialExceededError(err) { reqestFailedError, ok := errors.ErrgoRoot(err).(*http.RequestFailedError) if !ok { - return errgo.Mask(err) + return errgo.Notef(err, "request to scale the application failed") } // In case of unprocessable, format and return a clear error