diff --git a/api/apierror.go b/api/apierror.go index 146e638189..3af1255408 100644 --- a/api/apierror.go +++ b/api/apierror.go @@ -2,9 +2,7 @@ package api import ( "errors" - "fmt" "net/http" - "strings" "google.golang.org/grpc/codes" ) @@ -28,27 +26,7 @@ func AsServerError(in error) *Error { // Error satisfies the error interface. func (e *Error) Error() string { - res := fmt.Sprintf("Status: %d, Code: %q, Error: %q", e.Status, e.Code, e.Message) - var dets []string - if e.Details != nil { - if e.Details.ErrorId != "" { - dets = append(dets, fmt.Sprintf("error_id: %q", e.Details.ErrorId)) - } - if e.Details.RequestId != "" { - dets = append(dets, fmt.Sprintf("request_id: %q", e.Details.RequestId)) - } - if e.Details.TraceId != "" { - dets = append(dets, fmt.Sprintf("TraceId: %q", e.Details.TraceId)) - } - for _, rf := range e.Details.RequestFields { - dets = append(dets, fmt.Sprintf("request_field: {name: %q, desc: %q}", rf.Name, rf.Description)) - } - } - if len(dets) > 0 { - det := strings.Join(dets, ", ") - res = fmt.Sprintf("%s, Details: {%s}", res, det) - } - return res + return e.responseBody.String() } // Errors are considered the same iff they are both api.Errors and their statuses are the same. diff --git a/internal/cmd/base/format.go b/internal/cmd/base/format.go index 74aa4f740a..da35e0a5ca 100644 --- a/internal/cmd/base/format.go +++ b/internal/cmd/base/format.go @@ -9,6 +9,7 @@ import ( "unicode" "unicode/utf8" + "github.com/hashicorp/boundary/api" "github.com/hashicorp/boundary/api/scopes" "github.com/mitchellh/cli" "github.com/mitchellh/go-wordwrap" @@ -133,6 +134,54 @@ func WrapMap(prefixSpaces, maxLengthOverride int, input map[string]interface{}) return strings.Join(ret, "\n") } +func PrintApiError(in *api.Error) string { + nonAttributeMap := map[string]interface{}{ + "Status": in.Status, + "Code": in.Code, + "Message": in.Message, + } + if in.Details != nil { + if in.Details.TraceId != "" { + nonAttributeMap["Trace ID"] = in.Details.TraceId + } + if in.Details.RequestId != "" { + nonAttributeMap["Request ID"] = in.Details.RequestId + } + if in.Details.ErrorId != "" { + nonAttributeMap["Error ID"] = in.Details.ErrorId + } + } + + maxLength := MaxAttributesLength(nonAttributeMap, nil, nil) + + ret := []string{ + "", + "Error information:", + WrapMap(2, maxLength+2, nonAttributeMap), + } + + if in.Details != nil { + if len(in.Details.RequestFields) > 0 { + ret = append(ret, + "", + " Field-specific Errors:", + ) + for _, field := range in.Details.RequestFields { + if field.Name == "update_mask" { + // TODO: Report useful error messages related to "update_mask". + continue + } + ret = append(ret, + fmt.Sprintf(" Name: -%s", strings.ReplaceAll(field.Name, "_", "-")), + fmt.Sprintf(" Error: %s", field.Description), + ) + } + } + } + + return WrapForHelpText(ret) +} + // An output formatter for json output of an object type JsonFormatter struct{} diff --git a/internal/cmd/commands/accounts/account.go b/internal/cmd/commands/accounts/account.go index 6cd8c34086..a44bb2f04c 100644 --- a/internal/cmd/commands/accounts/account.go +++ b/internal/cmd/commands/accounts/account.go @@ -279,8 +279,8 @@ func (c *Command) Run(args []string) int { plural = "accounts" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/accounts/password.go b/internal/cmd/commands/accounts/password.go index 215c3902be..e1784526f9 100644 --- a/internal/cmd/commands/accounts/password.go +++ b/internal/cmd/commands/accounts/password.go @@ -204,8 +204,8 @@ func (c *PasswordCommand) Run(args []string) int { plural := "password-type account" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/authenticate/password.go b/internal/cmd/commands/authenticate/password.go index b950db2987..4fddbdb190 100644 --- a/internal/cmd/commands/authenticate/password.go +++ b/internal/cmd/commands/authenticate/password.go @@ -127,8 +127,8 @@ func (c *PasswordCommand) Run(args []string) int { "password": c.flagPassword, }) if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing authentication: %s", err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing authentication: %s", base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to perform authentication: %s", err.Error())) diff --git a/internal/cmd/commands/authmethods/authmethod.go b/internal/cmd/commands/authmethods/authmethod.go index 065bfc097c..61087dbba8 100644 --- a/internal/cmd/commands/authmethods/authmethod.go +++ b/internal/cmd/commands/authmethods/authmethod.go @@ -175,8 +175,8 @@ func (c *Command) Run(args []string) int { plural = "auth methods" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/authmethods/password.go b/internal/cmd/commands/authmethods/password.go index 4a26c07413..8034c85cc0 100644 --- a/internal/cmd/commands/authmethods/password.go +++ b/internal/cmd/commands/authmethods/password.go @@ -194,8 +194,8 @@ func (c *PasswordCommand) Run(args []string) int { plural := "password-type auth-method" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/authtokens/authtokens.go b/internal/cmd/commands/authtokens/authtokens.go index e0a2b77ba7..3df12bf205 100644 --- a/internal/cmd/commands/authtokens/authtokens.go +++ b/internal/cmd/commands/authtokens/authtokens.go @@ -112,8 +112,8 @@ func (c *Command) Run(args []string) int { plural = "auth tokens" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/groups/group.go b/internal/cmd/commands/groups/group.go index 20d9b0521f..ed60d813c0 100644 --- a/internal/cmd/commands/groups/group.go +++ b/internal/cmd/commands/groups/group.go @@ -193,8 +193,8 @@ func (c *Command) Run(args []string) int { plural = "groups" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hostcatalogs/hostcatalog.go b/internal/cmd/commands/hostcatalogs/hostcatalog.go index 422aaff31c..1f94af938b 100644 --- a/internal/cmd/commands/hostcatalogs/hostcatalog.go +++ b/internal/cmd/commands/hostcatalogs/hostcatalog.go @@ -175,8 +175,8 @@ func (c *Command) Run(args []string) int { plural = "host catalogs" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hostcatalogs/static.go b/internal/cmd/commands/hostcatalogs/static.go index bd00978082..1372de0786 100644 --- a/internal/cmd/commands/hostcatalogs/static.go +++ b/internal/cmd/commands/hostcatalogs/static.go @@ -150,8 +150,8 @@ func (c *StaticCommand) Run(args []string) int { plural := "static-type host-catalog" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hosts/host.go b/internal/cmd/commands/hosts/host.go index 59a1fa040d..b20f332f92 100644 --- a/internal/cmd/commands/hosts/host.go +++ b/internal/cmd/commands/hosts/host.go @@ -173,8 +173,8 @@ func (c *Command) Run(args []string) int { plural = "hosts" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hosts/static.go b/internal/cmd/commands/hosts/static.go index 091203758d..194be1abd0 100644 --- a/internal/cmd/commands/hosts/static.go +++ b/internal/cmd/commands/hosts/static.go @@ -178,8 +178,8 @@ func (c *StaticCommand) Run(args []string) int { plural := "static-type host" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hostsets/hostset.go b/internal/cmd/commands/hostsets/hostset.go index 8bb755e556..23964ff6a2 100644 --- a/internal/cmd/commands/hostsets/hostset.go +++ b/internal/cmd/commands/hostsets/hostset.go @@ -265,8 +265,8 @@ func (c *Command) Run(args []string) int { plural = "host sets" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/hostsets/static.go b/internal/cmd/commands/hostsets/static.go index 852524a3a4..147c3bbc8e 100644 --- a/internal/cmd/commands/hostsets/static.go +++ b/internal/cmd/commands/hostsets/static.go @@ -148,8 +148,8 @@ func (c *StaticCommand) Run(args []string) int { plural := "static-type host-set" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/proxy/proxy.go b/internal/cmd/commands/proxy/proxy.go index 03ac11e46e..508c246406 100644 --- a/internal/cmd/commands/proxy/proxy.go +++ b/internal/cmd/commands/proxy/proxy.go @@ -456,8 +456,8 @@ func (c *Command) Run(args []string) (retCode int) { sar, err := targetClient.AuthorizeSession(c.Context, c.flagTargetId, opts...) if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing authorize-session against target: %s", err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing authorize-session against target: %s", base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to authorize a session against target: %s", err.Error())) diff --git a/internal/cmd/commands/roles/role.go b/internal/cmd/commands/roles/role.go index 377f094e2e..729dae4fc6 100644 --- a/internal/cmd/commands/roles/role.go +++ b/internal/cmd/commands/roles/role.go @@ -244,8 +244,8 @@ func (c *Command) Run(args []string) int { plural = "roles" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/scopes/scope.go b/internal/cmd/commands/scopes/scope.go index 5b529593cd..1e9ac0ea23 100644 --- a/internal/cmd/commands/scopes/scope.go +++ b/internal/cmd/commands/scopes/scope.go @@ -171,8 +171,8 @@ func (c *Command) Run(args []string) int { plural = "scopes" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/sessions/session.go b/internal/cmd/commands/sessions/session.go index 4333abef40..85659fd6c9 100644 --- a/internal/cmd/commands/sessions/session.go +++ b/internal/cmd/commands/sessions/session.go @@ -130,8 +130,8 @@ func (c *Command) Run(args []string) int { plural = "sessions" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/targets/target.go b/internal/cmd/commands/targets/target.go index 3d84dc251c..432c556dfb 100644 --- a/internal/cmd/commands/targets/target.go +++ b/internal/cmd/commands/targets/target.go @@ -294,8 +294,8 @@ func (c *Command) Run(args []string) int { plural = "a session against target" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/targets/tcp.go b/internal/cmd/commands/targets/tcp.go index 5ee74d8cbe..3ab82f619b 100644 --- a/internal/cmd/commands/targets/tcp.go +++ b/internal/cmd/commands/targets/tcp.go @@ -222,8 +222,8 @@ func (c *TcpCommand) Run(args []string) int { plural := "tcp-type target" if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error())) diff --git a/internal/cmd/commands/users/user.go b/internal/cmd/commands/users/user.go index 79d7d0dea2..f5f40ef172 100644 --- a/internal/cmd/commands/users/user.go +++ b/internal/cmd/commands/users/user.go @@ -193,8 +193,8 @@ func (c *Command) Run(args []string) int { plural = "users" } if err != nil { - if api.AsServerError(err) != nil { - c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, err.Error())) + if apiErr := api.AsServerError(err); apiErr != nil { + c.UI.Error(fmt.Sprintf("Error from controller when performing %s on %s: %s", c.Func, plural, base.PrintApiError(apiErr))) return 1 } c.UI.Error(fmt.Sprintf("Error trying to %s %s: %s", c.Func, plural, err.Error()))