Change Format of API Error (#784)

This is a wire breaking change for json errors since we have removed and renamed a few fields, and changed part of the structure of the returned json error.

* Remove redundant fields in Status, details.error_id, details.TraceId and details.request_id from API errors.

* Added wrapped errors and "ops" field to indicate the internal operation of the errors returned by the API.

* Added error cli error reporting of Op and wrapped errors.
pull/811/head
Todd Knight 5 years ago committed by GitHub
parent 18ea39b237
commit aa4157639c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -25,22 +25,24 @@ type Account struct {
AuthMethodId string `json:"auth_method_id,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Account) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Account) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Account) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type AccountReadResult struct {
Item *Account
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Account
response *api.Response
}
func (n AccountReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n AccountReadResult) GetItem() interface{} {
}
func (n AccountReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AccountReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AccountCreateResult = AccountReadResult
type AccountUpdateResult = AccountReadResult
type AccountDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n AccountDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AccountDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AccountListResult struct {
Items []*Account
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Account
response *api.Response
}
func (n AccountListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n AccountListResult) GetItems() interface{} {
}
func (n AccountListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AccountListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -147,8 +147,7 @@ func (c *Client) Create(ctx context.Context, authMethodId string, opt ...Option)
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -189,8 +188,7 @@ func (c *Client) Read(ctx context.Context, accountId string, opt ...Option) (*Ac
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -253,8 +251,7 @@ func (c *Client) Update(ctx context.Context, accountId string, version uint32, o
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -295,8 +292,7 @@ func (c *Client) Delete(ctx context.Context, accountId string, opt ...Option) (*
}
target := &AccountDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -338,7 +334,6 @@ func (c *Client) List(ctx context.Context, authMethodId string, opt ...Option) (
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -8,10 +8,10 @@ import (
)
var (
ErrNotFound = &Error{Status: http.StatusNotFound, Code: codes.NotFound.String()}
ErrInvalidArgument = &Error{Status: http.StatusBadRequest, Code: codes.InvalidArgument.String()}
ErrPermissionDenied = &Error{Status: http.StatusForbidden, Code: codes.PermissionDenied.String()}
ErrUnauthorized = &Error{Status: http.StatusUnauthorized, Code: codes.Unauthenticated.String()}
ErrNotFound = &Error{Kind: codes.NotFound.String(), response: &Response{resp: &http.Response{StatusCode: http.StatusNotFound}}}
ErrInvalidArgument = &Error{Kind: codes.InvalidArgument.String(), response: &Response{resp: &http.Response{StatusCode: http.StatusBadRequest}}}
ErrPermissionDenied = &Error{Kind: codes.PermissionDenied.String(), response: &Response{resp: &http.Response{StatusCode: http.StatusForbidden}}}
ErrUnauthorized = &Error{Kind: codes.Unauthenticated.String(), response: &Response{resp: &http.Response{StatusCode: http.StatusUnauthorized}}}
)
// AsServerError returns an api *Error from the provided error. If the provided error
@ -26,11 +26,11 @@ func AsServerError(in error) *Error {
// Error satisfies the error interface.
func (e *Error) Error() string {
return e.responseBody.String()
return e.response.Body.String()
}
// Errors are considered the same iff they are both api.Errors and their statuses are the same.
func (e *Error) Is(target error) bool {
tApiErr := AsServerError(target)
return tApiErr != nil && tApiErr.Code == e.Code && tApiErr.Status == e.Status
return tApiErr != nil && tApiErr.Kind == e.Kind && e.ResponseStatus() == tApiErr.ResponseStatus()
}

@ -25,22 +25,24 @@ type AuthMethod struct {
Type string `json:"type,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n AuthMethod) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthMethod) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n AuthMethod) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type AuthMethodReadResult struct {
Item *AuthMethod
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *AuthMethod
response *api.Response
}
func (n AuthMethodReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n AuthMethodReadResult) GetItem() interface{} {
}
func (n AuthMethodReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthMethodReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AuthMethodCreateResult = AuthMethodReadResult
type AuthMethodUpdateResult = AuthMethodReadResult
type AuthMethodDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n AuthMethodDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthMethodDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AuthMethodListResult struct {
Items []*AuthMethod
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*AuthMethod
response *api.Response
}
func (n AuthMethodListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n AuthMethodListResult) GetItems() interface{} {
}
func (n AuthMethodListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthMethodListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -152,8 +152,7 @@ func (c *Client) Create(ctx context.Context, resourceType string, scopeId string
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -194,8 +193,7 @@ func (c *Client) Read(ctx context.Context, authMethodId string, opt ...Option) (
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -258,8 +256,7 @@ func (c *Client) Update(ctx context.Context, authMethodId string, version uint32
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -300,8 +297,7 @@ func (c *Client) Delete(ctx context.Context, authMethodId string, opt ...Option)
}
target := &AuthMethodDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -343,7 +339,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Auth
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -25,22 +25,24 @@ type AuthToken struct {
ApproximateLastUsedTime time.Time `json:"approximate_last_used_time,omitempty"`
ExpirationTime time.Time `json:"expiration_time,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n AuthToken) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthToken) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n AuthToken) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type AuthTokenReadResult struct {
Item *AuthToken
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *AuthToken
response *api.Response
}
func (n AuthTokenReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n AuthTokenReadResult) GetItem() interface{} {
}
func (n AuthTokenReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthTokenReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AuthTokenCreateResult = AuthTokenReadResult
type AuthTokenUpdateResult = AuthTokenReadResult
type AuthTokenDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n AuthTokenDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthTokenDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type AuthTokenListResult struct {
Items []*AuthToken
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*AuthToken
response *api.Response
}
func (n AuthTokenListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n AuthTokenListResult) GetItems() interface{} {
}
func (n AuthTokenListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n AuthTokenListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -144,8 +144,7 @@ func (c *Client) Read(ctx context.Context, authTokenId string, opt ...Option) (*
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -186,8 +185,7 @@ func (c *Client) Delete(ctx context.Context, authTokenId string, opt ...Option)
}
target := &AuthTokenDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -229,7 +227,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Auth
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -4,19 +4,22 @@ package api
import "bytes"
type Error struct {
Status int32 `json:"status,omitempty"`
Code string `json:"code,omitempty"`
Kind string `json:"kind,omitempty"`
Op string `json:"op,omitempty"`
Message string `json:"message,omitempty"`
Details *ErrorDetails `json:"details,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *Response
}
func (n Error) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Error) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Error) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}

@ -2,8 +2,6 @@
package api
type ErrorDetails struct {
TraceId string `json:"TraceId,omitempty"`
RequestId string `json:"request_id,omitempty"`
ErrorId string `json:"error_id,omitempty"`
RequestFields []*FieldError `json:"request_fields,omitempty"`
RequestFields []*FieldError `json:"request_fields,omitempty"`
WrappedErrors []*WrappedError `json:"wrapped_errors,omitempty"`
}

@ -25,22 +25,24 @@ type Group struct {
MemberIds []string `json:"member_ids,omitempty"`
Members []*Member `json:"members,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Group) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Group) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Group) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type GroupReadResult struct {
Item *Group
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Group
response *api.Response
}
func (n GroupReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n GroupReadResult) GetItem() interface{} {
}
func (n GroupReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n GroupReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type GroupCreateResult = GroupReadResult
type GroupUpdateResult = GroupReadResult
type GroupDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n GroupDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n GroupDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type GroupListResult struct {
Items []*Group
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Group
response *api.Response
}
func (n GroupListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n GroupListResult) GetItems() interface{} {
}
func (n GroupListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n GroupListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -147,8 +147,7 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Gr
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -189,8 +188,7 @@ func (c *Client) Read(ctx context.Context, groupId string, opt ...Option) (*Grou
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -253,8 +251,7 @@ func (c *Client) Update(ctx context.Context, groupId string, version uint32, opt
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -295,8 +292,7 @@ func (c *Client) Delete(ctx context.Context, groupId string, opt ...Option) (*Gr
}
target := &GroupDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -338,8 +334,7 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Grou
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -406,8 +401,7 @@ func (c *Client) AddMembers(ctx context.Context, groupId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -472,8 +466,7 @@ func (c *Client) SetMembers(ctx context.Context, groupId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -540,7 +533,6 @@ func (c *Client) RemoveMembers(ctx context.Context, groupId string, version uint
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -25,22 +25,24 @@ type HostCatalog struct {
Type string `json:"type,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n HostCatalog) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostCatalog) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n HostCatalog) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type HostCatalogReadResult struct {
Item *HostCatalog
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *HostCatalog
response *api.Response
}
func (n HostCatalogReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n HostCatalogReadResult) GetItem() interface{} {
}
func (n HostCatalogReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostCatalogReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostCatalogCreateResult = HostCatalogReadResult
type HostCatalogUpdateResult = HostCatalogReadResult
type HostCatalogDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n HostCatalogDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostCatalogDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostCatalogListResult struct {
Items []*HostCatalog
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*HostCatalog
response *api.Response
}
func (n HostCatalogListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n HostCatalogListResult) GetItems() interface{} {
}
func (n HostCatalogListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostCatalogListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -152,8 +152,7 @@ func (c *Client) Create(ctx context.Context, resourceType string, scopeId string
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -194,8 +193,7 @@ func (c *Client) Read(ctx context.Context, hostCatalogId string, opt ...Option)
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -258,8 +256,7 @@ func (c *Client) Update(ctx context.Context, hostCatalogId string, version uint3
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -300,8 +297,7 @@ func (c *Client) Delete(ctx context.Context, hostCatalogId string, opt ...Option
}
target := &HostCatalogDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -343,7 +339,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Host
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -26,22 +26,24 @@ type Host struct {
HostSetIds []string `json:"host_set_ids,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Host) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Host) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Host) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type HostReadResult struct {
Item *Host
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Host
response *api.Response
}
func (n HostReadResult) GetItem() interface{} {
@ -49,33 +51,31 @@ func (n HostReadResult) GetItem() interface{} {
}
func (n HostReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostCreateResult = HostReadResult
type HostUpdateResult = HostReadResult
type HostDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n HostDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostListResult struct {
Items []*Host
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Host
response *api.Response
}
func (n HostListResult) GetItems() interface{} {
@ -83,11 +83,11 @@ func (n HostListResult) GetItems() interface{} {
}
func (n HostListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -148,8 +148,7 @@ func (c *Client) Create(ctx context.Context, hostCatalogId string, opt ...Option
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -190,8 +189,7 @@ func (c *Client) Read(ctx context.Context, hostId string, opt ...Option) (*HostR
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -254,8 +252,7 @@ func (c *Client) Update(ctx context.Context, hostId string, version uint32, opt
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -296,8 +293,7 @@ func (c *Client) Delete(ctx context.Context, hostId string, opt ...Option) (*Hos
}
target := &HostDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -339,7 +335,6 @@ func (c *Client) List(ctx context.Context, hostCatalogId string, opt ...Option)
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -26,22 +26,24 @@ type HostSet struct {
HostIds []string `json:"host_ids,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n HostSet) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostSet) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n HostSet) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type HostSetReadResult struct {
Item *HostSet
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *HostSet
response *api.Response
}
func (n HostSetReadResult) GetItem() interface{} {
@ -49,33 +51,31 @@ func (n HostSetReadResult) GetItem() interface{} {
}
func (n HostSetReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostSetReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostSetCreateResult = HostSetReadResult
type HostSetUpdateResult = HostSetReadResult
type HostSetDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n HostSetDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostSetDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type HostSetListResult struct {
Items []*HostSet
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*HostSet
response *api.Response
}
func (n HostSetListResult) GetItems() interface{} {
@ -83,11 +83,11 @@ func (n HostSetListResult) GetItems() interface{} {
}
func (n HostSetListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n HostSetListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -148,8 +148,7 @@ func (c *Client) Create(ctx context.Context, hostCatalogId string, opt ...Option
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -190,8 +189,7 @@ func (c *Client) Read(ctx context.Context, hostSetId string, opt ...Option) (*Ho
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -254,8 +252,7 @@ func (c *Client) Update(ctx context.Context, hostSetId string, version uint32, o
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -296,8 +293,7 @@ func (c *Client) Delete(ctx context.Context, hostSetId string, opt ...Option) (*
}
target := &HostSetDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -339,8 +335,7 @@ func (c *Client) List(ctx context.Context, hostCatalogId string, opt ...Option)
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -407,8 +402,7 @@ func (c *Client) AddHosts(ctx context.Context, hostSetId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -473,8 +467,7 @@ func (c *Client) SetHosts(ctx context.Context, hostSetId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -541,7 +534,6 @@ func (c *Client) RemoveHosts(ctx context.Context, hostSetId string, version uint
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -33,18 +33,12 @@ func (r *Response) Decode(inStruct interface{}) (*Error, error) {
return nil, nil
}
// TODO Remove as we'll use the common err format for this
if r.resp.StatusCode == 403 {
// Nothing to be done
return &Error{
Status: http.StatusForbidden,
Message: "Forbidden",
}, nil
if r.resp.StatusCode >= 400 {
// If the status code is >= 400 the body of the response will be the
// json representation of the Error struct so we decode it as such.
inStruct = &Error{}
}
apiErr := &Error{
Status: int32(r.resp.StatusCode),
}
if r.resp.Body != nil {
r.Body = new(bytes.Buffer)
if _, err := r.Body.ReadFrom(r.resp.Body); err != nil {
@ -55,9 +49,6 @@ func (r *Response) Decode(inStruct interface{}) (*Error, error) {
reader := bytes.NewReader(r.Body.Bytes())
dec := json.NewDecoder(reader)
dec.UseNumber()
if r.resp.StatusCode >= 400 {
inStruct = apiErr
}
r.Map = make(map[string]interface{})
if err := dec.Decode(&r.Map); err != nil {
return nil, fmt.Errorf("error decoding response to map: %w; response was %s", err, r.Body.String())
@ -71,10 +62,10 @@ func (r *Response) Decode(inStruct interface{}) (*Error, error) {
}
}
}
if r.resp.StatusCode >= 400 {
errStruct := inStruct.(*Error)
errStruct.responseBody = r.Body
errStruct.responseMap = r.Map
apiErr := inStruct.(*Error)
apiErr.response = r
return apiErr, nil
}

@ -28,22 +28,24 @@ type Role struct {
GrantStrings []string `json:"grant_strings,omitempty"`
Grants []*Grant `json:"grants,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Role) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Role) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Role) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type RoleReadResult struct {
Item *Role
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Role
response *api.Response
}
func (n RoleReadResult) GetItem() interface{} {
@ -51,33 +53,31 @@ func (n RoleReadResult) GetItem() interface{} {
}
func (n RoleReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n RoleReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type RoleCreateResult = RoleReadResult
type RoleUpdateResult = RoleReadResult
type RoleDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n RoleDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n RoleDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type RoleListResult struct {
Items []*Role
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Role
response *api.Response
}
func (n RoleListResult) GetItems() interface{} {
@ -85,11 +85,11 @@ func (n RoleListResult) GetItems() interface{} {
}
func (n RoleListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n RoleListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -150,8 +150,7 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Ro
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -192,8 +191,7 @@ func (c *Client) Read(ctx context.Context, roleId string, opt ...Option) (*RoleR
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -256,8 +254,7 @@ func (c *Client) Update(ctx context.Context, roleId string, version uint32, opt
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -298,8 +295,7 @@ func (c *Client) Delete(ctx context.Context, roleId string, opt ...Option) (*Rol
}
target := &RoleDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -341,8 +337,7 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Role
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -409,8 +404,7 @@ func (c *Client) AddGrants(ctx context.Context, roleId string, version uint32, g
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -477,8 +471,7 @@ func (c *Client) AddPrincipals(ctx context.Context, roleId string, version uint3
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -543,8 +536,7 @@ func (c *Client) SetGrants(ctx context.Context, roleId string, version uint32, g
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -609,8 +601,7 @@ func (c *Client) SetPrincipals(ctx context.Context, roleId string, version uint3
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -677,8 +668,7 @@ func (c *Client) RemoveGrants(ctx context.Context, roleId string, version uint32
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -745,7 +735,6 @@ func (c *Client) RemovePrincipals(ctx context.Context, roleId string, version ui
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -23,22 +23,24 @@ type Scope struct {
Version uint32 `json:"version,omitempty"`
Type string `json:"type,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Scope) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Scope) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Scope) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type ScopeReadResult struct {
Item *Scope
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Scope
response *api.Response
}
func (n ScopeReadResult) GetItem() interface{} {
@ -46,33 +48,31 @@ func (n ScopeReadResult) GetItem() interface{} {
}
func (n ScopeReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n ScopeReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type ScopeCreateResult = ScopeReadResult
type ScopeUpdateResult = ScopeReadResult
type ScopeDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n ScopeDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n ScopeDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type ScopeListResult struct {
Items []*Scope
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Scope
response *api.Response
}
func (n ScopeListResult) GetItems() interface{} {
@ -80,11 +80,11 @@ func (n ScopeListResult) GetItems() interface{} {
}
func (n ScopeListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n ScopeListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -145,8 +145,7 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Sc
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -187,8 +186,7 @@ func (c *Client) Read(ctx context.Context, scopeId string, opt ...Option) (*Scop
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -251,8 +249,7 @@ func (c *Client) Update(ctx context.Context, scopeId string, version uint32, opt
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -293,8 +290,7 @@ func (c *Client) Delete(ctx context.Context, scopeId string, opt ...Option) (*Sc
}
target := &ScopeDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -336,7 +332,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Scop
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -68,7 +68,6 @@ func (c *Client) Cancel(ctx context.Context, sessionId string, version uint32, o
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -33,22 +33,24 @@ type Session struct {
Certificate []byte `json:"certificate,omitempty"`
TerminationReason string `json:"termination_reason,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Session) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Session) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Session) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type SessionReadResult struct {
Item *Session
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Session
response *api.Response
}
func (n SessionReadResult) GetItem() interface{} {
@ -56,33 +58,31 @@ func (n SessionReadResult) GetItem() interface{} {
}
func (n SessionReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n SessionReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type SessionCreateResult = SessionReadResult
type SessionUpdateResult = SessionReadResult
type SessionDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n SessionDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n SessionDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type SessionListResult struct {
Items []*Session
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Session
response *api.Response
}
func (n SessionListResult) GetItems() interface{} {
@ -90,11 +90,11 @@ func (n SessionListResult) GetItems() interface{} {
}
func (n SessionListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n SessionListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -152,8 +152,7 @@ func (c *Client) Read(ctx context.Context, sessionId string, opt ...Option) (*Se
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -194,7 +193,6 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Sess
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -29,22 +29,24 @@ type Target struct {
SessionConnectionLimit int32 `json:"session_connection_limit,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n Target) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n Target) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n Target) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type TargetReadResult struct {
Item *Target
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *Target
response *api.Response
}
func (n TargetReadResult) GetItem() interface{} {
@ -52,33 +54,31 @@ func (n TargetReadResult) GetItem() interface{} {
}
func (n TargetReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n TargetReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type TargetCreateResult = TargetReadResult
type TargetUpdateResult = TargetReadResult
type TargetDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n TargetDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n TargetDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type TargetListResult struct {
Items []*Target
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*Target
response *api.Response
}
func (n TargetListResult) GetItems() interface{} {
@ -86,11 +86,11 @@ func (n TargetListResult) GetItems() interface{} {
}
func (n TargetListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n TargetListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -156,8 +156,7 @@ func (c *Client) Create(ctx context.Context, resourceType string, scopeId string
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -198,8 +197,7 @@ func (c *Client) Read(ctx context.Context, targetId string, opt ...Option) (*Tar
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -262,8 +260,7 @@ func (c *Client) Update(ctx context.Context, targetId string, version uint32, op
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -304,8 +301,7 @@ func (c *Client) Delete(ctx context.Context, targetId string, opt ...Option) (*T
}
target := &TargetDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -347,8 +343,7 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*Targ
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -415,8 +410,7 @@ func (c *Client) AddHostSets(ctx context.Context, targetId string, version uint3
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -481,8 +475,7 @@ func (c *Client) SetHostSets(ctx context.Context, targetId string, version uint3
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -549,7 +542,6 @@ func (c *Client) RemoveHostSets(ctx context.Context, targetId string, version ui
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -25,22 +25,24 @@ type User struct {
AccountIds []string `json:"account_ids,omitempty"`
Accounts []*Account `json:"accounts,omitempty"`
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n User) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n User) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n User) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
type UserReadResult struct {
Item *User
responseBody *bytes.Buffer
responseMap map[string]interface{}
Item *User
response *api.Response
}
func (n UserReadResult) GetItem() interface{} {
@ -48,33 +50,31 @@ func (n UserReadResult) GetItem() interface{} {
}
func (n UserReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n UserReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type UserCreateResult = UserReadResult
type UserUpdateResult = UserReadResult
type UserDeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n UserDeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n UserDeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type UserListResult struct {
Items []*User
responseBody *bytes.Buffer
responseMap map[string]interface{}
Items []*User
response *api.Response
}
func (n UserListResult) GetItems() interface{} {
@ -82,11 +82,11 @@ func (n UserListResult) GetItems() interface{} {
}
func (n UserListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n UserListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
// Client is a client for this collection
@ -147,8 +147,7 @@ func (c *Client) Create(ctx context.Context, scopeId string, opt ...Option) (*Us
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -189,8 +188,7 @@ func (c *Client) Read(ctx context.Context, userId string, opt ...Option) (*UserR
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -253,8 +251,7 @@ func (c *Client) Update(ctx context.Context, userId string, version uint32, opt
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -295,8 +292,7 @@ func (c *Client) Delete(ctx context.Context, userId string, opt ...Option) (*Use
}
target := &UserDeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -338,8 +334,7 @@ func (c *Client) List(ctx context.Context, scopeId string, opt ...Option) (*User
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -406,8 +401,7 @@ func (c *Client) AddAccounts(ctx context.Context, userId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -472,8 +466,7 @@ func (c *Client) SetAccounts(ctx context.Context, userId string, version uint32,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
@ -540,7 +533,6 @@ func (c *Client) RemoveAccounts(ctx context.Context, userId string, version uint
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}

@ -0,0 +1,7 @@
// Code generated by "make api"; DO NOT EDIT.
package api
type WrappedError struct {
Op string `json:"op,omitempty"`
Message string `json:"message,omitempty"`
}

@ -102,6 +102,11 @@ var inputStructs = []*structInfo{
outFile: "error_details.gen.go",
outputOnly: true,
},
{
inProto: &api.WrappedError{},
outFile: "wrapped_error.gen.go",
outputOnly: true,
},
{
inProto: &api.FieldError{},
outFile: "field_error.gen.go",

@ -220,8 +220,7 @@ func (c *Client) List(ctx context.Context, {{ .CollectionFunctionArg }} string,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
`))
@ -264,8 +263,7 @@ func (c *Client) Read(ctx context.Context, {{ .ResourceFunctionArg }} string, op
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
`))
@ -308,8 +306,7 @@ func (c *Client) Delete(ctx context.Context, {{ .ResourceFunctionArg }} string,
}
target := &{{ .Name }}DeleteResult{
responseBody: resp.Body,
responseMap: resp.Map,
response: resp,
}
return target, nil
}
@ -367,8 +364,7 @@ func (c *Client) Create (ctx context.Context, {{ if .TypeOnCreate }} resourceTyp
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
`))
@ -435,8 +431,7 @@ func (c *Client) Update(ctx context.Context, {{ .ResourceFunctionArg }} string,
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
`))
@ -519,8 +514,7 @@ func (c *Client) {{ $fullName }}(ctx context.Context, {{ $input.ResourceFunction
if apiErr != nil {
return nil, apiErr
}
target.responseBody = resp.Body
target.responseMap = resp.Map
target.response = resp
return target, nil
}
{{ end }}
@ -544,27 +538,31 @@ import (
type {{ .Name }} struct { {{ range .Fields }}
{{ .Name }} {{ .FieldType }} `, "`json:\"{{ .ProtoName }},omitempty\"`", `{{ end }}
{{ if ( or .CreateResponseTypes ( eq .Name "Error" ) ) }}
responseBody *bytes.Buffer
responseMap map[string]interface{}
{{ if .CreateResponseTypes }}
response *api.Response
{{ else if ( eq .Name "Error" ) }}
response *Response
{{ end }}
}
{{ if ( or .CreateResponseTypes ( eq .Name "Error" ) ) }}
func (n {{ .Name }}) ResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n {{ .Name }}) ResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
func (n {{ .Name }}) ResponseStatus() int {
return n.response.HttpResponse().StatusCode
}
{{ end }}
{{ if .CreateResponseTypes }}
type {{ .Name }}ReadResult struct {
Item *{{ .Name }}
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n {{ .Name }}ReadResult) GetItem() interface{} {
@ -572,33 +570,31 @@ func (n {{ .Name }}ReadResult) GetItem() interface{} {
}
func (n {{ .Name }}ReadResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n {{ .Name }}ReadResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type {{ .Name }}CreateResult = {{ .Name }}ReadResult
type {{ .Name }}UpdateResult = {{ .Name }}ReadResult
type {{ .Name }}DeleteResult struct {
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n {{ .Name }}DeleteResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n {{ .Name }}DeleteResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
type {{ .Name }}ListResult struct {
Items []*{{ .Name }}
responseBody *bytes.Buffer
responseMap map[string]interface{}
response *api.Response
}
func (n {{ .Name }}ListResult) GetItems() interface{} {
@ -606,11 +602,11 @@ func (n {{ .Name }}ListResult) GetItems() interface{} {
}
func (n {{ .Name }}ListResult) GetResponseBody() *bytes.Buffer {
return n.responseBody
return n.response.Body
}
func (n {{ .Name }}ListResult) GetResponseMap() map[string]interface{} {
return n.responseMap
return n.response.Map
}
{{ end }}
`)))

@ -136,20 +136,13 @@ func WrapMap(prefixSpaces, maxLengthOverride int, input map[string]interface{})
func PrintApiError(in *api.Error) string {
nonAttributeMap := map[string]interface{}{
"Status": in.Status,
"Code": in.Code,
"Status": in.ResponseStatus(),
"Kind": in.Kind,
"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
}
if in.Op != "" {
nonAttributeMap["Operation"] = in.Op
}
maxLength := MaxAttributesLength(nonAttributeMap, nil, nil)
@ -161,6 +154,19 @@ func PrintApiError(in *api.Error) string {
}
if in.Details != nil {
if len(in.Details.WrappedErrors) > 0 {
ret = append(ret,
"",
" Wrapped Errors:",
)
for _, we := range in.Details.WrappedErrors {
ret = append(ret,
fmt.Sprintf(" Message: %s", we.Message),
fmt.Sprintf(" Operation: %s", we.Op),
)
}
}
if len(in.Details.RequestFields) > 0 {
ret = append(ret,
"",

@ -266,7 +266,7 @@ func (c *Command) Run(args []string) int {
result, err = accountClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = accountClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -156,7 +156,7 @@ func (c *Command) Run(args []string) int {
result, err = authmethodClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = authmethodClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -99,7 +99,7 @@ func (c *Command) Run(args []string) int {
result, err = authtokenClient.Read(c.Context, c.FlagId)
case "delete":
_, err = authtokenClient.Delete(c.Context, c.FlagId)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -170,7 +170,7 @@ func (c *Command) Run(args []string) int {
result, err = groupClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = groupClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -157,7 +157,7 @@ func (c *Command) Run(args []string) int {
result, err = hostcatalogClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = hostcatalogClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -156,7 +156,7 @@ func (c *Command) Run(args []string) int {
result, err = hostClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = hostClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -245,7 +245,7 @@ func (c *Command) Run(args []string) int {
result, err = hostsetClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = hostsetClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -217,7 +217,7 @@ func (c *Command) Run(args []string) int {
result, err = roleClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = roleClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -156,7 +156,7 @@ func (c *Command) Run(args []string) int {
result, err = scopeClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = scopeClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -345,7 +345,7 @@ func (c *Command) Run(args []string) int {
result, err = targetClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = targetClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -170,7 +170,7 @@ func (c *Command) Run(args []string) int {
result, err = userClient.Read(c.Context, c.FlagId, opts...)
case "delete":
_, err = userClient.Delete(c.Context, c.FlagId, opts...)
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.Status == int32(http.StatusNotFound) {
if apiErr := api.AsServerError(err); apiErr != nil && apiErr.ResponseStatus() == http.StatusNotFound {
existed = false
err = nil
}

@ -25,23 +25,19 @@ const (
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type ErrorDetails struct {
// Error information relevant to an error that was wrapped by the backend.
type WrappedError struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The TraceId that can be used for OpenTelemetry.
TraceId string `protobuf:"bytes,1,opt,name=TraceId,proto3" json:"TraceId,omitempty"`
// A request ID.
RequestId string `protobuf:"bytes,2,opt,name=request_id,proto3" json:"request_id,omitempty"`
// An Error ID.
ErrorId string `protobuf:"bytes,3,opt,name=error_id,proto3" json:"error_id,omitempty"`
// Request-field-specific error details.
RequestFields []*FieldError `protobuf:"bytes,4,rep,name=request_fields,proto3" json:"request_fields,omitempty"`
// An string indicating what operation was being run when the wrapped error was created.
Op string `protobuf:"bytes,1,opt,name=op,proto3" json:"op,omitempty"`
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
}
func (x *ErrorDetails) Reset() {
*x = ErrorDetails{}
func (x *WrappedError) Reset() {
*x = WrappedError{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_v1_error_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -49,13 +45,13 @@ func (x *ErrorDetails) Reset() {
}
}
func (x *ErrorDetails) String() string {
func (x *WrappedError) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ErrorDetails) ProtoMessage() {}
func (*WrappedError) ProtoMessage() {}
func (x *ErrorDetails) ProtoReflect() protoreflect.Message {
func (x *WrappedError) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_v1_error_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
@ -67,30 +63,67 @@ func (x *ErrorDetails) ProtoReflect() protoreflect.Message {
return mi.MessageOf(x)
}
// Deprecated: Use ErrorDetails.ProtoReflect.Descriptor instead.
func (*ErrorDetails) Descriptor() ([]byte, []int) {
// Deprecated: Use WrappedError.ProtoReflect.Descriptor instead.
func (*WrappedError) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{0}
}
func (x *ErrorDetails) GetTraceId() string {
func (x *WrappedError) GetOp() string {
if x != nil {
return x.TraceId
return x.Op
}
return ""
}
func (x *ErrorDetails) GetRequestId() string {
func (x *WrappedError) GetMessage() string {
if x != nil {
return x.RequestId
return x.Message
}
return ""
}
func (x *ErrorDetails) GetErrorId() string {
if x != nil {
return x.ErrorId
// Additional details regarding a specific error.
type ErrorDetails struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Request-field-specific error details.
RequestFields []*FieldError `protobuf:"bytes,1,rep,name=request_fields,proto3" json:"request_fields,omitempty"`
// The errors that were wrapped in the backend for this returned error.
WrappedErrors []*WrappedError `protobuf:"bytes,2,rep,name=wrapped_errors,proto3" json:"wrapped_errors,omitempty"`
}
func (x *ErrorDetails) Reset() {
*x = ErrorDetails{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_v1_error_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
return ""
}
func (x *ErrorDetails) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ErrorDetails) ProtoMessage() {}
func (x *ErrorDetails) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_v1_error_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ErrorDetails.ProtoReflect.Descriptor instead.
func (*ErrorDetails) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{1}
}
func (x *ErrorDetails) GetRequestFields() []*FieldError {
@ -100,6 +133,13 @@ func (x *ErrorDetails) GetRequestFields() []*FieldError {
return nil
}
func (x *ErrorDetails) GetWrappedErrors() []*WrappedError {
if x != nil {
return x.WrappedErrors
}
return nil
}
// FieldErrors contains error information on a per field basis.
type FieldError struct {
state protoimpl.MessageState
@ -115,7 +155,7 @@ type FieldError struct {
func (x *FieldError) Reset() {
*x = FieldError{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_v1_error_proto_msgTypes[1]
mi := &file_controller_api_v1_error_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -128,7 +168,7 @@ func (x *FieldError) String() string {
func (*FieldError) ProtoMessage() {}
func (x *FieldError) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_v1_error_proto_msgTypes[1]
mi := &file_controller_api_v1_error_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -141,7 +181,7 @@ func (x *FieldError) ProtoReflect() protoreflect.Message {
// Deprecated: Use FieldError.ProtoReflect.Descriptor instead.
func (*FieldError) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{1}
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{2}
}
func (x *FieldError) GetName() string {
@ -164,10 +204,10 @@ type Error struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The HTTP Status code applicable to this error.
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
// An application-specific error string.
Code string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
// The kind of error this is.
Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
// An string indicating what operation was being run when the error was returned.
Op string `protobuf:"bytes,2,opt,name=op,proto3" json:"op,omitempty"`
// A human-readable explanation specific to this occurrence of the error.
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
// Additional metadata regarding the error. Depending on the error, different fields will be populated.
@ -177,7 +217,7 @@ type Error struct {
func (x *Error) Reset() {
*x = Error{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_v1_error_proto_msgTypes[2]
mi := &file_controller_api_v1_error_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -190,7 +230,7 @@ func (x *Error) String() string {
func (*Error) ProtoMessage() {}
func (x *Error) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_v1_error_proto_msgTypes[2]
mi := &file_controller_api_v1_error_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -203,19 +243,19 @@ func (x *Error) ProtoReflect() protoreflect.Message {
// Deprecated: Use Error.ProtoReflect.Descriptor instead.
func (*Error) Descriptor() ([]byte, []int) {
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{2}
return file_controller_api_v1_error_proto_rawDescGZIP(), []int{3}
}
func (x *Error) GetStatus() int32 {
func (x *Error) GetKind() string {
if x != nil {
return x.Status
return x.Kind
}
return 0
return ""
}
func (x *Error) GetCode() string {
func (x *Error) GetOp() string {
if x != nil {
return x.Code
return x.Op
}
return ""
}
@ -240,35 +280,37 @@ var file_controller_api_v1_error_proto_rawDesc = []byte{
0x0a, 0x1d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x76, 0x31, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x11, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x22, 0xab, 0x01, 0x0a, 0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61,
0x69, 0x6c, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x54, 0x72, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a,
0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x12, 0x1a, 0x0a,
0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x12, 0x45, 0x0a, 0x0e, 0x72, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72,
0x52, 0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73,
0x22, 0x42, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x88, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x16,
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06,
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44,
0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42,
0x3f, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61,
0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79,
0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70, 0x69,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x76, 0x31, 0x22, 0x38, 0x0a, 0x0c, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x6f, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x9e, 0x01, 0x0a,
0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x45, 0x0a,
0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c,
0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45,
0x72, 0x72, 0x6f, 0x72, 0x52, 0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x66, 0x69,
0x65, 0x6c, 0x64, 0x73, 0x12, 0x47, 0x0a, 0x0e, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f,
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0e, 0x77,
0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x42, 0x0a,
0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x22, 0x80, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6b,
0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12,
0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x70, 0x12,
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x45,
0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x52, 0x07, 0x64, 0x65, 0x74,
0x61, 0x69, 0x6c, 0x73, 0x42, 0x3f, 0x5a, 0x3d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75,
0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67,
0x65, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70,
0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -283,20 +325,22 @@ func file_controller_api_v1_error_proto_rawDescGZIP() []byte {
return file_controller_api_v1_error_proto_rawDescData
}
var file_controller_api_v1_error_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_controller_api_v1_error_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_controller_api_v1_error_proto_goTypes = []interface{}{
(*ErrorDetails)(nil), // 0: controller.api.v1.ErrorDetails
(*FieldError)(nil), // 1: controller.api.v1.FieldError
(*Error)(nil), // 2: controller.api.v1.Error
(*WrappedError)(nil), // 0: controller.api.v1.WrappedError
(*ErrorDetails)(nil), // 1: controller.api.v1.ErrorDetails
(*FieldError)(nil), // 2: controller.api.v1.FieldError
(*Error)(nil), // 3: controller.api.v1.Error
}
var file_controller_api_v1_error_proto_depIdxs = []int32{
1, // 0: controller.api.v1.ErrorDetails.request_fields:type_name -> controller.api.v1.FieldError
0, // 1: controller.api.v1.Error.details:type_name -> controller.api.v1.ErrorDetails
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
2, // 0: controller.api.v1.ErrorDetails.request_fields:type_name -> controller.api.v1.FieldError
0, // 1: controller.api.v1.ErrorDetails.wrapped_errors:type_name -> controller.api.v1.WrappedError
1, // 2: controller.api.v1.Error.details:type_name -> controller.api.v1.ErrorDetails
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_controller_api_v1_error_proto_init() }
@ -306,7 +350,7 @@ func file_controller_api_v1_error_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_controller_api_v1_error_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ErrorDetails); i {
switch v := v.(*WrappedError); i {
case 0:
return &v.state
case 1:
@ -318,7 +362,7 @@ func file_controller_api_v1_error_proto_init() {
}
}
file_controller_api_v1_error_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FieldError); i {
switch v := v.(*ErrorDetails); i {
case 0:
return &v.state
case 1:
@ -330,6 +374,18 @@ func file_controller_api_v1_error_proto_init() {
}
}
file_controller_api_v1_error_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*FieldError); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_v1_error_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Error); i {
case 0:
return &v.state
@ -348,7 +404,7 @@ func file_controller_api_v1_error_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_controller_api_v1_error_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},

@ -4,15 +4,20 @@ package controller.api.v1;
option go_package = "github.com/hashicorp/boundary/internal/gen/controller/api;api";
// Error information relevant to an error that was wrapped by the backend.
message WrappedError {
// An string indicating what operation was being run when the wrapped error was created.
string op = 1;
string message = 2;
}
// Additional details regarding a specific error.
message ErrorDetails {
// The TraceId that can be used for OpenTelemetry.
string TraceId = 1 [json_name="TraceId"];
// A request ID.
string request_id = 2 [json_name="request_id"];
// An Error ID.
string error_id = 3 [json_name="error_id"];
// Request-field-specific error details.
repeated FieldError request_fields = 4 [json_name="request_fields"];
repeated FieldError request_fields = 1 [json_name="request_fields"];
// The errors that were wrapped in the backend for this returned error.
repeated WrappedError wrapped_errors = 2 [json_name="wrapped_errors"];
}
// FieldErrors contains error information on a per field basis.
@ -26,10 +31,10 @@ message FieldError {
// Error is returned by the JSON API when an error occurs.
message Error {
// The HTTP Status code applicable to this error.
int32 status = 1;
// An application-specific error string.
string code = 2;
// The kind of error this is.
string kind = 1;
// An string indicating what operation was being run when the error was returned.
string op = 2;
// A human-readable explanation specific to this occurrence of the error.
string message = 3;
// Additional metadata regarding the error. Depending on the error, different fields will be populated.

@ -10,7 +10,6 @@ import (
"time"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/auth"
"github.com/hashicorp/boundary/internal/gen/controller/api/services"
@ -22,6 +21,8 @@ import (
"github.com/hashicorp/boundary/sdk/strutil"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/base62"
"google.golang.org/grpc/codes"
"github.com/hashicorp/boundary/internal/servers/controller/handlers"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/authtokens"
@ -175,6 +176,16 @@ func handleGrpcGateway(c *Controller, props HandlerProperties) (http.Handler, er
return mux, nil
}
// generatedTraceId returns a boundary generated TraceId or "" if an error occurs when generating
// the id.
func generatedTraceId() string {
t, err := base62.Random(20)
if err != nil {
return ""
}
return fmt.Sprintf("gtraceid_%s", t)
}
func wrapHandlerWithCommonFuncs(h http.Handler, c *Controller, props HandlerProperties) http.Handler {
var maxRequestDuration time.Duration
var maxRequestSize int64
@ -278,10 +289,7 @@ func wrapHandlerWithCors(h http.Handler, props HandlerProperties) http.Handler {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
err := &api.Error{
Status: http.StatusForbidden,
Code: "origin forbidden",
}
err := handlers.ApiErrorWithCodeAndMessage(codes.PermissionDenied, "origin forbidden")
enc := json.NewEncoder(w)
enc.Encode(err)

@ -12,7 +12,6 @@ import (
"github.com/hashicorp/boundary/internal/errors"
pb "github.com/hashicorp/boundary/internal/gen/controller/api"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/sdk/helper/base62"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
@ -23,11 +22,12 @@ const (
)
type apiError struct {
inner *pb.Error
status int32
inner *pb.Error
}
func (e *apiError) Error() string {
res := fmt.Sprintf("Status: %d, Code: %q, Error: %q", e.inner.GetStatus(), e.inner.GetCode(), e.inner.GetMessage())
res := fmt.Sprintf("Status: %d, Kind: %q, Error: %q", e.status, e.inner.GetKind(), e.inner.GetMessage())
var dets []string
for _, rf := range e.inner.GetDetails().GetRequestFields() {
dets = append(dets, fmt.Sprintf("{name: %q, desc: %q}", rf.GetName(), rf.GetDescription()))
@ -44,58 +44,64 @@ func (e *apiError) Is(target error) bool {
if !errors.As(target, &tApiErr) {
return false
}
return tApiErr.inner.Code == e.inner.Code && tApiErr.inner.Status == e.inner.Status
return tApiErr.inner.Kind == e.inner.Kind && tApiErr.status == e.status
}
// ApiErrorWithCode returns an api error with the provided code.
func ApiErrorWithCode(c codes.Code) error {
return &apiError{inner: &pb.Error{
Status: int32(runtime.HTTPStatusFromCode(c)),
Code: c.String(),
}}
return &apiError{
status: int32(runtime.HTTPStatusFromCode(c)),
inner: &pb.Error{
Kind: c.String(),
}}
}
// ApiErrorWithCodeAndMessage returns an api error with the provided code and message.
func ApiErrorWithCodeAndMessage(c codes.Code, msg string, args ...interface{}) error {
return &apiError{inner: &pb.Error{
Status: int32(runtime.HTTPStatusFromCode(c)),
Code: c.String(),
Message: fmt.Sprintf(msg, args...),
}}
return &apiError{
status: int32(runtime.HTTPStatusFromCode(c)),
inner: &pb.Error{
Kind: c.String(),
Message: fmt.Sprintf(msg, args...),
}}
}
// NotFoundError returns an ApiError indicating a resource couldn't be found.
func NotFoundError() error {
return &apiError{&pb.Error{
Status: http.StatusNotFound,
Code: codes.NotFound.String(),
Message: "Resource not found.",
}}
return &apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: codes.NotFound.String(),
Message: "Resource not found.",
}}
}
// NotFoundErrorf returns an ApiError indicating a resource couldn't be found.
func NotFoundErrorf(msg string, a ...interface{}) error {
return &apiError{&pb.Error{
Status: http.StatusNotFound,
Code: codes.NotFound.String(),
Message: fmt.Sprintf(msg, a...),
}}
return &apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: codes.NotFound.String(),
Message: fmt.Sprintf(msg, a...),
}}
}
func ForbiddenError() error {
return &apiError{&pb.Error{
Status: http.StatusForbidden,
Code: codes.PermissionDenied.String(),
Message: "Forbidden.",
}}
return &apiError{
status: http.StatusForbidden,
inner: &pb.Error{
Kind: codes.PermissionDenied.String(),
Message: "Forbidden.",
}}
}
func UnauthenticatedError() error {
return &apiError{&pb.Error{
Status: http.StatusUnauthorized,
Code: codes.Unauthenticated.String(),
Message: "Unauthenticated, or invalid token.",
}}
return &apiError{
status: http.StatusUnauthorized,
inner: &pb.Error{
Kind: codes.Unauthenticated.String(),
Message: "Unauthenticated, or invalid token.",
}}
}
func InvalidArgumentErrorf(msg string, fields map[string]string) error {
@ -125,18 +131,20 @@ func backendErrorToApiError(inErr error) error {
case errors.Is(inErr, runtime.ErrNotMatch):
// grpc gateway uses this error when the path was not matched, but the error uses codes.Unimplemented which doesn't match the intention.
// Overwrite the error to match our expected behavior.
return &apiError{inner: &pb.Error{
Status: http.StatusNotFound,
Code: codes.NotFound.String(),
Message: http.StatusText(http.StatusNotFound),
}}
return &apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: codes.NotFound.String(),
Message: http.StatusText(http.StatusNotFound),
}}
case status.Code(inErr) == codes.Unimplemented:
// Instead of returning a 501 we always want to return a 405 when a method isn't implemented.
return &apiError{inner: &pb.Error{
Status: http.StatusMethodNotAllowed,
Code: codes.Unimplemented.String(),
Message: stErr.Message(),
}}
return &apiError{
status: http.StatusMethodNotAllowed,
inner: &pb.Error{
Kind: codes.Unimplemented.String(),
Message: stErr.Message(),
}}
case errors.Is(inErr, errors.ErrRecordNotFound):
return NotFoundErrorf(genericNotFoundMsg)
case errors.Is(inErr, errors.ErrInvalidFieldMask), errors.Is(inErr, errors.ErrEmptyFieldMask):
@ -144,23 +152,14 @@ func backendErrorToApiError(inErr error) error {
case errors.IsUniqueError(inErr), errors.Is(inErr, errors.ErrNotUnique):
return InvalidArgumentErrorf(genericUniquenessMsg, nil)
}
return nil
}
func getInternalError(id string) *apiError {
return &apiError{&pb.Error{
Status: http.StatusInternalServerError,
Code: codes.Internal.String(),
Details: &pb.ErrorDetails{ErrorId: id},
}}
}
func internalErrorId() (string, error) {
errId, err := base62.Random(10)
if err != nil {
return "", fmt.Errorf("unable to generate id: %w", err)
// We haven't been able to identify what this backend error is, return it as an internal error
// TODO: Don't return potentially sensitive information (like which user id an account
// is already associated with when attempting to re-associate it).
return &apiError{
status: http.StatusInternalServerError,
inner: &pb.Error{Kind: codes.Internal.String(), Message: inErr.Error()},
}
return errId, nil
}
func ErrorHandler(logger hclog.Logger) runtime.ErrorHandlerFunc {
@ -175,14 +174,8 @@ func ErrorHandler(logger hclog.Logger) runtime.ErrorHandlerFunc {
}
}
if apiErr == nil || apiErr.inner.GetStatus() == http.StatusInternalServerError {
errId, err := internalErrorId()
if err != nil {
logger.Error("unable to generate internal error id", "error", err)
errId = "failed_to_generate_error_id"
}
logger.Error("internal error returned", "error id", errId, "error", inErr)
apiErr = getInternalError(errId)
if apiErr.status == http.StatusInternalServerError {
logger.Error("internal error returned", "error", inErr)
}
buf, merr := mar.Marshal(apiErr.inner)
@ -196,7 +189,7 @@ func ErrorHandler(logger hclog.Logger) runtime.ErrorHandlerFunc {
}
w.Header().Set("Content-Type", mar.ContentType(apiErr.inner))
w.WriteHeader(int(apiErr.inner.GetStatus()))
w.WriteHeader(int(apiErr.status))
if _, err := w.Write(buf); err != nil {
logger.Error("failed to send response chunk", "error", err)
return

@ -33,15 +33,17 @@ func TestApiErrorHandler(t *testing.T) {
testCases := []struct {
name string
err error
expected *pb.Error
expected apiError
}{
{
name: "Not Found",
err: NotFoundErrorf("Test"),
expected: &pb.Error{
Status: http.StatusNotFound,
Code: "NotFound",
Message: "Test",
expected: apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: "NotFound",
Message: "Test",
},
},
},
{
@ -50,19 +52,21 @@ func TestApiErrorHandler(t *testing.T) {
"k1": "v1",
"k2": "v2",
}),
expected: &pb.Error{
Status: http.StatusBadRequest,
Code: "InvalidArgument",
Message: "Test",
Details: &pb.ErrorDetails{
RequestFields: []*pb.FieldError{
{
Name: "k1",
Description: "v1",
},
{
Name: "k2",
Description: "v2",
expected: apiError{
status: http.StatusBadRequest,
inner: &pb.Error{
Kind: "InvalidArgument",
Message: "Test",
Details: &pb.ErrorDetails{
RequestFields: []*pb.FieldError{
{
Name: "k1",
Description: "v1",
},
{
Name: "k2",
Description: "v2",
},
},
},
},
@ -71,93 +75,113 @@ func TestApiErrorHandler(t *testing.T) {
{
name: "GrpcGateway Routing Error",
err: runtime.ErrNotMatch,
expected: &pb.Error{
Status: http.StatusNotFound,
Code: "NotFound",
Message: http.StatusText(http.StatusNotFound),
expected: apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: "NotFound",
Message: http.StatusText(http.StatusNotFound),
},
},
},
{
name: "Unimplemented error",
err: status.Error(codes.Unimplemented, "Test"),
expected: &pb.Error{
Status: http.StatusMethodNotAllowed,
Code: "Unimplemented",
Message: "Test",
expected: apiError{
status: http.StatusMethodNotAllowed,
inner: &pb.Error{
Kind: "Unimplemented",
Message: "Test",
},
},
},
{
name: "Unknown error",
err: stderrors.New("Some random error"),
expected: &pb.Error{
Status: http.StatusInternalServerError,
Code: "Internal",
Details: &pb.ErrorDetails{ErrorId: ""},
expected: apiError{
status: http.StatusInternalServerError,
inner: &pb.Error{
Kind: "Internal",
Message: "Some random error",
},
},
},
{
name: "Db invalid public id error",
err: fmt.Errorf("test error: %w", errors.ErrInvalidPublicId),
expected: &pb.Error{
Status: http.StatusInternalServerError,
Code: "Internal",
Details: &pb.ErrorDetails{ErrorId: ""},
expected: apiError{
status: http.StatusInternalServerError,
inner: &pb.Error{
Kind: "Internal",
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidPublicId),
},
},
},
{
name: "Db invalid parameter",
err: fmt.Errorf("test error: %w", errors.ErrInvalidParameter),
expected: &pb.Error{
Status: http.StatusInternalServerError,
Code: "Internal",
Details: &pb.ErrorDetails{ErrorId: ""},
expected: apiError{
status: http.StatusInternalServerError,
inner: &pb.Error{
Kind: "Internal",
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidParameter),
},
},
},
{
name: "Db invalid field mask",
err: fmt.Errorf("test error: %w", errors.ErrInvalidFieldMask),
expected: &pb.Error{
Status: http.StatusBadRequest,
Code: "InvalidArgument",
Message: "Error in provided request",
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
expected: apiError{
status: http.StatusBadRequest,
inner: &pb.Error{
Kind: "InvalidArgument",
Message: "Error in provided request",
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
},
},
},
{
name: "Db empty field mask",
err: fmt.Errorf("test error: %w", errors.ErrEmptyFieldMask),
expected: &pb.Error{
Status: http.StatusBadRequest,
Code: "InvalidArgument",
Message: "Error in provided request",
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
expected: apiError{
status: http.StatusBadRequest,
inner: &pb.Error{
Kind: "InvalidArgument",
Message: "Error in provided request",
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
},
},
},
{
name: "Db not unique",
err: fmt.Errorf("test error: %w", errors.ErrNotUnique),
expected: &pb.Error{
Status: http.StatusBadRequest,
Code: "InvalidArgument",
Message: genericUniquenessMsg,
expected: apiError{
status: http.StatusBadRequest,
inner: &pb.Error{
Kind: "InvalidArgument",
Message: genericUniquenessMsg,
},
},
},
{
name: "Db record not found",
err: fmt.Errorf("test error: %w", errors.ErrRecordNotFound),
expected: &pb.Error{
Status: http.StatusNotFound,
Code: "NotFound",
Message: genericNotFoundMsg,
expected: apiError{
status: http.StatusNotFound,
inner: &pb.Error{
Kind: "NotFound",
Message: genericNotFoundMsg,
},
},
},
{
name: "Db multiple records",
err: fmt.Errorf("test error: %w", errors.ErrMultipleRecords),
expected: &pb.Error{
Status: http.StatusInternalServerError,
Code: "Internal",
Details: &pb.ErrorDetails{ErrorId: ""},
expected: apiError{
status: http.StatusInternalServerError,
inner: &pb.Error{
Kind: "Internal",
Message: fmt.Sprintf("test error: %s", errors.ErrMultipleRecords),
},
},
},
}
@ -167,7 +191,7 @@ func TestApiErrorHandler(t *testing.T) {
w := httptest.NewRecorder()
tested(ctx, mux, outMarsh, w, req, tc.err)
resp := w.Result()
assert.EqualValues(tc.expected.Status, resp.StatusCode)
assert.EqualValues(tc.expected.status, resp.StatusCode)
got, err := ioutil.ReadAll(resp.Body)
require.NoError(err)
@ -176,12 +200,8 @@ func TestApiErrorHandler(t *testing.T) {
err = inMarsh.Unmarshal(got, gotErr)
require.NoError(err)
if tc.expected.Status == http.StatusInternalServerError {
require.NotNil(tc.expected.GetDetails())
tc.expected.GetDetails().ErrorId = gotErr.GetDetails().GetErrorId()
}
assert.Empty(cmp.Diff(tc.expected, gotErr, protocmp.Transform()))
assert.Equal(tc.expected.status, int32(resp.StatusCode))
assert.Empty(cmp.Diff(tc.expected.inner, gotErr, protocmp.Transform()))
})
}
}

@ -165,7 +165,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
// Create another resource with the same name.
_, err = accountClient.Create(tc.Context(), amId, accounts.WithPasswordAccountLoginName("first"))
@ -177,17 +177,17 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = accountClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
_, err = accountClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -32,5 +32,5 @@ func TestAuthenticate(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValuesf(http.StatusUnauthorized, apiErr.Status, "Expected unauthorized, got %q", apiErr.Message)
assert.EqualValuesf(http.StatusUnauthorized, apiErr.ResponseStatus(), "Expected unauthorized, got %q", apiErr.Message)
}

@ -145,11 +145,11 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = tokens.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -151,7 +151,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
})
}
}
@ -193,7 +193,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
// Create another resource with the same name.
_, err = groupClient.Create(tc.Context(), tt.scopeId, groups.WithName("first"))
@ -203,19 +203,19 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = groupClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
_, err = groupClient.Update(tc.Context(), g.Item.Id, g.Item.Version)
require.Error(err)
apiErr = api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
})
}
}

@ -109,7 +109,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
func TestErrors(t *testing.T) {
@ -134,7 +134,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = pc.Create(tc.Context(), "static", proj.GetPublicId(), hostcatalogs.WithName("foo"))
require.Error(err)
@ -145,11 +145,11 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = pc.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -119,7 +119,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
func TestErrors(t *testing.T) {
@ -147,7 +147,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = hClient.Create(tc.Context(), hc.Item.Id, hosts.WithName("foo"), hosts.WithStaticHostAddress("someaddress"))
require.Error(err)
@ -158,11 +158,11 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = hClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -156,7 +156,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
require.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
// TODO: Get better coverage for expected errors and error formats.
@ -185,7 +185,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
h, err = hClient.Create(tc.Context(), hc.Item.Id, hostsets.WithName("foo"))
require.Error(err)
@ -197,11 +197,11 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = hClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -284,7 +284,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
// Create another resource with the same name.
_, err = roleClient.Create(tc.Context(), tt.scopeId, roles.WithName("first"))
@ -296,19 +296,19 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = roleClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
_, err = roleClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
})
}
}

@ -98,7 +98,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
func TestErrors(t *testing.T) {
@ -122,17 +122,17 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = scps.Read(tc.Context(), "p_doesntexis")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = scps.Read(tc.Context(), "invalid id")
assert.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -152,7 +152,7 @@ func TestCrud(t *testing.T) {
assert.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
func TestSet_Errors(t *testing.T) {
@ -176,7 +176,7 @@ func TestSet_Errors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
tar, err = tarClient.Create(tc.Context(), "tcp", proj.GetPublicId(), targets.WithName("foo"))
require.Error(err)
@ -188,11 +188,11 @@ func TestSet_Errors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = tarClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

@ -148,7 +148,7 @@ func TestCrud(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
}
func TestErrors(t *testing.T) {
@ -171,7 +171,7 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr := api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
// Create another resource with the same name.
_, err = userClient.Create(tc.Context(), org.GetPublicId(), users.WithName("first"))
@ -183,17 +183,17 @@ func TestErrors(t *testing.T) {
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusNotFound, apiErr.Status)
assert.EqualValues(http.StatusNotFound, apiErr.ResponseStatus())
_, err = userClient.Read(tc.Context(), "invalid id")
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
_, err = userClient.Update(tc.Context(), u.Item.Id, u.Item.Version)
require.Error(err)
apiErr = api.AsServerError(err)
assert.NotNil(apiErr)
assert.EqualValues(http.StatusBadRequest, apiErr.Status)
assert.EqualValues(http.StatusBadRequest, apiErr.ResponseStatus())
}

Loading…
Cancel
Save