[#15] Use extended error response

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-07-07 15:59:38 +03:00 committed by Alex Vanin
parent e28c6e5375
commit 9fba8d7f23
22 changed files with 528 additions and 174 deletions

View file

@ -60,7 +60,7 @@ const (
// tests configuration. // tests configuration.
useWalletConnect = false useWalletConnect = false
useLocalEnvironment = false useLocalEnvironment = true
) )
func TestIntegration(t *testing.T) { func TestIntegration(t *testing.T) {

View file

@ -0,0 +1,131 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// ErrorResponse error response
//
// swagger:model ErrorResponse
type ErrorResponse struct {
// code
Code int64 `json:"code,omitempty"`
// message
// Required: true
Message *string `json:"message"`
// type
// Required: true
Type *ErrorType `json:"type"`
}
// Validate validates this error response
func (m *ErrorResponse) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateMessage(formats); err != nil {
res = append(res, err)
}
if err := m.validateType(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ErrorResponse) validateMessage(formats strfmt.Registry) error {
if err := validate.Required("message", "body", m.Message); err != nil {
return err
}
return nil
}
func (m *ErrorResponse) validateType(formats strfmt.Registry) error {
if err := validate.Required("type", "body", m.Type); err != nil {
return err
}
if err := validate.Required("type", "body", m.Type); err != nil {
return err
}
if m.Type != nil {
if err := m.Type.Validate(formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("type")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("type")
}
return err
}
}
return nil
}
// ContextValidate validate this error response based on the context it is used
func (m *ErrorResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
var res []error
if err := m.contextValidateType(ctx, formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *ErrorResponse) contextValidateType(ctx context.Context, formats strfmt.Registry) error {
if m.Type != nil {
if err := m.Type.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("type")
} else if ce, ok := err.(*errors.CompositeError); ok {
return ce.ValidateName("type")
}
return err
}
}
return nil
}
// MarshalBinary interface implementation
func (m *ErrorResponse) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *ErrorResponse) UnmarshalBinary(b []byte) error {
var res ErrorResponse
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

78
gen/models/error_type.go Normal file
View file

@ -0,0 +1,78 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"encoding/json"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/validate"
)
// ErrorType error type
//
// swagger:model ErrorType
type ErrorType string
func NewErrorType(value ErrorType) *ErrorType {
return &value
}
// Pointer returns a pointer to a freshly-allocated ErrorType.
func (m ErrorType) Pointer() *ErrorType {
return &m
}
const (
// ErrorTypeGW captures enum value "GW"
ErrorTypeGW ErrorType = "GW"
// ErrorTypeAPI captures enum value "API"
ErrorTypeAPI ErrorType = "API"
)
// for schema
var errorTypeEnum []interface{}
func init() {
var res []ErrorType
if err := json.Unmarshal([]byte(`["GW","API"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
errorTypeEnum = append(errorTypeEnum, v)
}
}
func (m ErrorType) validateErrorTypeEnum(path, location string, value ErrorType) error {
if err := validate.EnumCase(path, location, value, errorTypeEnum, true); err != nil {
return err
}
return nil
}
// Validate validates this error type
func (m ErrorType) Validate(formats strfmt.Registry) error {
var res []error
// value enum
if err := m.validateErrorTypeEnum("", "body", m); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// ContextValidate validates this error type based on context it is used
func (m ErrorType) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}

View file

@ -82,7 +82,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -128,7 +128,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -200,7 +200,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -221,7 +221,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -250,7 +250,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -276,7 +276,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -314,7 +314,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -356,7 +356,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -414,7 +414,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -469,7 +469,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -487,7 +487,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -671,9 +671,31 @@ func init() {
} }
} }
}, },
"Error": { "ErrorResponse": {
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"code": {
"type": "integer"
},
"message": {
"type": "string" "type": "string"
}, },
"type": {
"$ref": "#/definitions/ErrorType"
}
}
},
"ErrorType": {
"type": "string",
"enum": [
"GW",
"API"
]
},
"Filter": { "Filter": {
"type": "object", "type": "object",
"required": [ "required": [
@ -1154,7 +1176,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1201,7 +1223,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1285,7 +1307,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1306,7 +1328,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1347,7 +1369,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1377,7 +1399,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1427,7 +1449,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1473,7 +1495,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1544,7 +1566,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1617,7 +1639,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1635,7 +1657,7 @@ func init() {
"400": { "400": {
"description": "Bad request", "description": "Bad request",
"schema": { "schema": {
"$ref": "#/definitions/Error" "$ref": "#/definitions/ErrorResponse"
} }
} }
} }
@ -1839,9 +1861,31 @@ func init() {
} }
} }
}, },
"Error": { "ErrorResponse": {
"type": "object",
"required": [
"type",
"message"
],
"properties": {
"code": {
"type": "integer"
},
"message": {
"type": "string" "type": "string"
}, },
"type": {
"$ref": "#/definitions/ErrorType"
}
}
},
"ErrorType": {
"type": "string",
"enum": [
"GW",
"API"
]
},
"Filter": { "Filter": {
"type": "object", "type": "object",
"required": [ "required": [

View file

@ -72,7 +72,7 @@ type AuthBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewAuthBadRequest creates AuthBadRequest with default headers values // NewAuthBadRequest creates AuthBadRequest with default headers values
@ -82,13 +82,13 @@ func NewAuthBadRequest() *AuthBadRequest {
} }
// WithPayload adds the payload to the auth bad request response // WithPayload adds the payload to the auth bad request response
func (o *AuthBadRequest) WithPayload(payload models.Error) *AuthBadRequest { func (o *AuthBadRequest) WithPayload(payload *models.ErrorResponse) *AuthBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the auth bad request response // SetPayload sets the payload to the auth bad request response
func (o *AuthBadRequest) SetPayload(payload models.Error) { func (o *AuthBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -96,8 +96,10 @@ func (o *AuthBadRequest) SetPayload(payload models.Error) {
func (o *AuthBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *AuthBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type DeleteContainerBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewDeleteContainerBadRequest creates DeleteContainerBadRequest with default headers values // NewDeleteContainerBadRequest creates DeleteContainerBadRequest with default headers values
@ -79,13 +79,13 @@ func NewDeleteContainerBadRequest() *DeleteContainerBadRequest {
} }
// WithPayload adds the payload to the delete container bad request response // WithPayload adds the payload to the delete container bad request response
func (o *DeleteContainerBadRequest) WithPayload(payload models.Error) *DeleteContainerBadRequest { func (o *DeleteContainerBadRequest) WithPayload(payload *models.ErrorResponse) *DeleteContainerBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the delete container bad request response // SetPayload sets the payload to the delete container bad request response
func (o *DeleteContainerBadRequest) SetPayload(payload models.Error) { func (o *DeleteContainerBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *DeleteContainerBadRequest) SetPayload(payload models.Error) {
func (o *DeleteContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *DeleteContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type DeleteObjectBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewDeleteObjectBadRequest creates DeleteObjectBadRequest with default headers values // NewDeleteObjectBadRequest creates DeleteObjectBadRequest with default headers values
@ -79,13 +79,13 @@ func NewDeleteObjectBadRequest() *DeleteObjectBadRequest {
} }
// WithPayload adds the payload to the delete object bad request response // WithPayload adds the payload to the delete object bad request response
func (o *DeleteObjectBadRequest) WithPayload(payload models.Error) *DeleteObjectBadRequest { func (o *DeleteObjectBadRequest) WithPayload(payload *models.ErrorResponse) *DeleteObjectBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the delete object bad request response // SetPayload sets the payload to the delete object bad request response
func (o *DeleteObjectBadRequest) SetPayload(payload models.Error) { func (o *DeleteObjectBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *DeleteObjectBadRequest) SetPayload(payload models.Error) {
func (o *DeleteObjectBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *DeleteObjectBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type GetContainerEACLBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewGetContainerEACLBadRequest creates GetContainerEACLBadRequest with default headers values // NewGetContainerEACLBadRequest creates GetContainerEACLBadRequest with default headers values
@ -79,13 +79,13 @@ func NewGetContainerEACLBadRequest() *GetContainerEACLBadRequest {
} }
// WithPayload adds the payload to the get container e Acl bad request response // WithPayload adds the payload to the get container e Acl bad request response
func (o *GetContainerEACLBadRequest) WithPayload(payload models.Error) *GetContainerEACLBadRequest { func (o *GetContainerEACLBadRequest) WithPayload(payload *models.ErrorResponse) *GetContainerEACLBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the get container e Acl bad request response // SetPayload sets the payload to the get container e Acl bad request response
func (o *GetContainerEACLBadRequest) SetPayload(payload models.Error) { func (o *GetContainerEACLBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *GetContainerEACLBadRequest) SetPayload(payload models.Error) {
func (o *GetContainerEACLBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *GetContainerEACLBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type GetContainerBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewGetContainerBadRequest creates GetContainerBadRequest with default headers values // NewGetContainerBadRequest creates GetContainerBadRequest with default headers values
@ -79,13 +79,13 @@ func NewGetContainerBadRequest() *GetContainerBadRequest {
} }
// WithPayload adds the payload to the get container bad request response // WithPayload adds the payload to the get container bad request response
func (o *GetContainerBadRequest) WithPayload(payload models.Error) *GetContainerBadRequest { func (o *GetContainerBadRequest) WithPayload(payload *models.ErrorResponse) *GetContainerBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the get container bad request response // SetPayload sets the payload to the get container bad request response
func (o *GetContainerBadRequest) SetPayload(payload models.Error) { func (o *GetContainerBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *GetContainerBadRequest) SetPayload(payload models.Error) {
func (o *GetContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *GetContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type GetObjectInfoBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewGetObjectInfoBadRequest creates GetObjectInfoBadRequest with default headers values // NewGetObjectInfoBadRequest creates GetObjectInfoBadRequest with default headers values
@ -79,13 +79,13 @@ func NewGetObjectInfoBadRequest() *GetObjectInfoBadRequest {
} }
// WithPayload adds the payload to the get object info bad request response // WithPayload adds the payload to the get object info bad request response
func (o *GetObjectInfoBadRequest) WithPayload(payload models.Error) *GetObjectInfoBadRequest { func (o *GetObjectInfoBadRequest) WithPayload(payload *models.ErrorResponse) *GetObjectInfoBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the get object info bad request response // SetPayload sets the payload to the get object info bad request response
func (o *GetObjectInfoBadRequest) SetPayload(payload models.Error) { func (o *GetObjectInfoBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *GetObjectInfoBadRequest) SetPayload(payload models.Error) {
func (o *GetObjectInfoBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *GetObjectInfoBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type ListContainersBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewListContainersBadRequest creates ListContainersBadRequest with default headers values // NewListContainersBadRequest creates ListContainersBadRequest with default headers values
@ -79,13 +79,13 @@ func NewListContainersBadRequest() *ListContainersBadRequest {
} }
// WithPayload adds the payload to the list containers bad request response // WithPayload adds the payload to the list containers bad request response
func (o *ListContainersBadRequest) WithPayload(payload models.Error) *ListContainersBadRequest { func (o *ListContainersBadRequest) WithPayload(payload *models.ErrorResponse) *ListContainersBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the list containers bad request response // SetPayload sets the payload to the list containers bad request response
func (o *ListContainersBadRequest) SetPayload(payload models.Error) { func (o *ListContainersBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *ListContainersBadRequest) SetPayload(payload models.Error) {
func (o *ListContainersBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *ListContainersBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type PutContainerEACLBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewPutContainerEACLBadRequest creates PutContainerEACLBadRequest with default headers values // NewPutContainerEACLBadRequest creates PutContainerEACLBadRequest with default headers values
@ -79,13 +79,13 @@ func NewPutContainerEACLBadRequest() *PutContainerEACLBadRequest {
} }
// WithPayload adds the payload to the put container e Acl bad request response // WithPayload adds the payload to the put container e Acl bad request response
func (o *PutContainerEACLBadRequest) WithPayload(payload models.Error) *PutContainerEACLBadRequest { func (o *PutContainerEACLBadRequest) WithPayload(payload *models.ErrorResponse) *PutContainerEACLBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the put container e Acl bad request response // SetPayload sets the payload to the put container e Acl bad request response
func (o *PutContainerEACLBadRequest) SetPayload(payload models.Error) { func (o *PutContainerEACLBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *PutContainerEACLBadRequest) SetPayload(payload models.Error) {
func (o *PutContainerEACLBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *PutContainerEACLBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type PutContainerBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewPutContainerBadRequest creates PutContainerBadRequest with default headers values // NewPutContainerBadRequest creates PutContainerBadRequest with default headers values
@ -79,13 +79,13 @@ func NewPutContainerBadRequest() *PutContainerBadRequest {
} }
// WithPayload adds the payload to the put container bad request response // WithPayload adds the payload to the put container bad request response
func (o *PutContainerBadRequest) WithPayload(payload models.Error) *PutContainerBadRequest { func (o *PutContainerBadRequest) WithPayload(payload *models.ErrorResponse) *PutContainerBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the put container bad request response // SetPayload sets the payload to the put container bad request response
func (o *PutContainerBadRequest) SetPayload(payload models.Error) { func (o *PutContainerBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *PutContainerBadRequest) SetPayload(payload models.Error) {
func (o *PutContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *PutContainerBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type PutObjectBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewPutObjectBadRequest creates PutObjectBadRequest with default headers values // NewPutObjectBadRequest creates PutObjectBadRequest with default headers values
@ -79,13 +79,13 @@ func NewPutObjectBadRequest() *PutObjectBadRequest {
} }
// WithPayload adds the payload to the put object bad request response // WithPayload adds the payload to the put object bad request response
func (o *PutObjectBadRequest) WithPayload(payload models.Error) *PutObjectBadRequest { func (o *PutObjectBadRequest) WithPayload(payload *models.ErrorResponse) *PutObjectBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the put object bad request response // SetPayload sets the payload to the put object bad request response
func (o *PutObjectBadRequest) SetPayload(payload models.Error) { func (o *PutObjectBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *PutObjectBadRequest) SetPayload(payload models.Error) {
func (o *PutObjectBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *PutObjectBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -69,7 +69,7 @@ type SearchObjectsBadRequest struct {
/* /*
In: Body In: Body
*/ */
Payload models.Error `json:"body,omitempty"` Payload *models.ErrorResponse `json:"body,omitempty"`
} }
// NewSearchObjectsBadRequest creates SearchObjectsBadRequest with default headers values // NewSearchObjectsBadRequest creates SearchObjectsBadRequest with default headers values
@ -79,13 +79,13 @@ func NewSearchObjectsBadRequest() *SearchObjectsBadRequest {
} }
// WithPayload adds the payload to the search objects bad request response // WithPayload adds the payload to the search objects bad request response
func (o *SearchObjectsBadRequest) WithPayload(payload models.Error) *SearchObjectsBadRequest { func (o *SearchObjectsBadRequest) WithPayload(payload *models.ErrorResponse) *SearchObjectsBadRequest {
o.Payload = payload o.Payload = payload
return o return o
} }
// SetPayload sets the payload to the search objects bad request response // SetPayload sets the payload to the search objects bad request response
func (o *SearchObjectsBadRequest) SetPayload(payload models.Error) { func (o *SearchObjectsBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload o.Payload = payload
} }
@ -93,8 +93,10 @@ func (o *SearchObjectsBadRequest) SetPayload(payload models.Error) {
func (o *SearchObjectsBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { func (o *SearchObjectsBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400) rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload payload := o.Payload
if err := producer.Produce(rw, payload); err != nil { if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this panic(err) // let the recovery middleware deal with this
} }
} }
}

View file

@ -11,6 +11,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-rest-gw/gen/models" "github.com/nspcc-dev/neofs-rest-gw/gen/models"
"github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations" "github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations"
"github.com/nspcc-dev/neofs-rest-gw/internal/util"
"github.com/nspcc-dev/neofs-sdk-go/pool" "github.com/nspcc-dev/neofs-sdk-go/pool"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -113,3 +114,9 @@ func (a *API) setupGlobalMiddleware(handler http.Handler) http.Handler {
handler.ServeHTTP(w, r.WithContext(ctx)) handler.ServeHTTP(w, r.WithContext(ctx))
}) })
} }
func (a *API) logAndGetErrorResponse(msg string, err error, fields ...zap.Field) *models.ErrorResponse {
fields = append(fields, zap.Error(err))
a.log.Error(msg, fields...)
return util.NewErrorResponse(fmt.Errorf("%s: %w", msg, err))
}

View file

@ -71,13 +71,14 @@ func (a *API) PostAuth(params operations.AuthParams) middleware.Responder {
response := make([]*models.TokenResponse, len(params.Tokens)) response := make([]*models.TokenResponse, len(params.Tokens))
for i, token := range params.Tokens { for i, token := range params.Tokens {
if _, ok := tokenNames[token.Name]; ok { if _, ok := tokenNames[token.Name]; ok {
return operations.NewAuthBadRequest().WithPayload(models.Error(fmt.Sprintf("duplicated token name '%s'", token.Name))) err := fmt.Errorf("duplicated token name '%s'", token.Name)
return operations.NewAuthBadRequest().WithPayload(util.NewErrorResponse(err))
} }
tokenNames[token.Name] = struct{}{} tokenNames[token.Name] = struct{}{}
isObject, err := IsObjectToken(token) isObject, err := IsObjectToken(token)
if err != nil { if err != nil {
return operations.NewAuthBadRequest().WithPayload(models.Error(err.Error())) return operations.NewAuthBadRequest().WithPayload(util.NewErrorResponse(err))
} }
if isObject { if isObject {
@ -88,7 +89,7 @@ func (a *API) PostAuth(params operations.AuthParams) middleware.Responder {
response[i], err = prepareContainerTokens(ctx, prm, a.pool, a.key.PublicKey()) response[i], err = prepareContainerTokens(ctx, prm, a.pool, a.key.PublicKey())
} }
if err != nil { if err != nil {
return operations.NewAuthBadRequest().WithPayload(models.Error(err.Error())) return operations.NewAuthBadRequest().WithPayload(util.NewErrorResponse(err))
} }
} }

View file

@ -43,14 +43,16 @@ func (a *API) PutContainers(params operations.PutContainerParams, principal *mod
} }
stoken, err := prepareSessionToken(bt, *params.WalletConnect) stoken, err := prepareSessionToken(bt, *params.WalletConnect)
if err != nil { if err != nil {
return wrapError(err) resp := a.logAndGetErrorResponse("invalid session token", err)
return operations.NewPutContainerBadRequest().WithPayload(resp)
} }
userAttributes := prepareUserAttributes(params.HTTPRequest.Header) userAttributes := prepareUserAttributes(params.HTTPRequest.Header)
cnrID, err := createContainer(params.HTTPRequest.Context(), a.pool, stoken, &params, userAttributes) cnrID, err := createContainer(params.HTTPRequest.Context(), a.pool, stoken, &params, userAttributes)
if err != nil { if err != nil {
return wrapError(err) resp := a.logAndGetErrorResponse("create container", err)
return operations.NewPutContainerBadRequest().WithPayload(resp)
} }
var resp operations.PutContainerOKBody var resp operations.PutContainerOKBody
@ -63,7 +65,8 @@ func (a *API) PutContainers(params operations.PutContainerParams, principal *mod
func (a *API) GetContainer(params operations.GetContainerParams) middleware.Responder { func (a *API) GetContainer(params operations.GetContainerParams) middleware.Responder {
cnr, err := getContainer(params.HTTPRequest.Context(), a.pool, params.ContainerID) cnr, err := getContainer(params.HTTPRequest.Context(), a.pool, params.ContainerID)
if err != nil { if err != nil {
return wrapError(err) resp := a.logAndGetErrorResponse("get container", err)
return operations.NewPutContainerBadRequest().WithPayload(resp)
} }
attrs := make([]*models.Attribute, len(cnr.Attributes())) attrs := make([]*models.Attribute, len(cnr.Attributes()))
@ -90,8 +93,8 @@ func (a *API) GetContainer(params operations.GetContainerParams) middleware.Resp
func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, principal *models.Principal) middleware.Responder { func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, principal *models.Principal) middleware.Responder {
cnrID, err := parseContainerID(params.ContainerID) cnrID, err := parseContainerID(params.ContainerID)
if err != nil { if err != nil {
a.log.Error("invalid container id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid container id", err)
return operations.NewPutContainerEACLBadRequest().WithPayload("invalid container id") return operations.NewPutContainerEACLBadRequest().WithPayload(resp)
} }
bt := &BearerToken{ bt := &BearerToken{
@ -101,12 +104,13 @@ func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, princip
} }
stoken, err := prepareSessionToken(bt, *params.WalletConnect) stoken, err := prepareSessionToken(bt, *params.WalletConnect)
if err != nil { if err != nil {
return wrapError(err) resp := a.logAndGetErrorResponse("invalid session token", err)
return operations.NewPutContainerEACLBadRequest().WithPayload(resp)
} }
if err = setContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID, stoken, params.Eacl); err != nil { if err = setContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID, stoken, params.Eacl); err != nil {
a.log.Error("failed set container eacl", zap.Error(err)) resp := a.logAndGetErrorResponse("failed set container eacl", err)
return operations.NewPutContainerEACLBadRequest().WithPayload(util.NewError(err)) return operations.NewPutContainerEACLBadRequest().WithPayload(resp)
} }
return operations.NewPutContainerEACLOK().WithPayload(util.NewSuccessResponse()) return operations.NewPutContainerEACLOK().WithPayload(util.NewSuccessResponse())
@ -116,14 +120,14 @@ func (a *API) PutContainerEACL(params operations.PutContainerEACLParams, princip
func (a *API) GetContainerEACL(params operations.GetContainerEACLParams) middleware.Responder { func (a *API) GetContainerEACL(params operations.GetContainerEACLParams) middleware.Responder {
cnrID, err := parseContainerID(params.ContainerID) cnrID, err := parseContainerID(params.ContainerID)
if err != nil { if err != nil {
a.log.Error("invalid container id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid container id", err)
return operations.NewGetContainerEACLBadRequest().WithPayload("invalid container id") return operations.NewGetContainerEACLBadRequest().WithPayload(resp)
} }
resp, err := getContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID) resp, err := getContainerEACL(params.HTTPRequest.Context(), a.pool, cnrID)
if err != nil { if err != nil {
a.log.Error("failed to get container eacl", zap.Error(err)) errResp := a.logAndGetErrorResponse("failed to get container eacl", err)
return operations.NewGetContainerEACLBadRequest().WithPayload("failed to get container eacl") return operations.NewGetContainerEACLBadRequest().WithPayload(errResp)
} }
return operations.NewGetContainerEACLOK().WithPayload(resp) return operations.NewGetContainerEACLOK().WithPayload(resp)
@ -135,8 +139,8 @@ func (a *API) ListContainer(params operations.ListContainersParams) middleware.R
var ownerID owner.ID var ownerID owner.ID
if err := ownerID.Parse(params.OwnerID); err != nil { if err := ownerID.Parse(params.OwnerID); err != nil {
a.log.Error("invalid owner id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid owner id", err)
return operations.NewListContainersBadRequest().WithPayload("invalid owner id") return operations.NewListContainersBadRequest().WithPayload(resp)
} }
var prm pool.PrmContainerList var prm pool.PrmContainerList
@ -144,8 +148,8 @@ func (a *API) ListContainer(params operations.ListContainersParams) middleware.R
ids, err := a.pool.ListContainers(ctx, prm) ids, err := a.pool.ListContainers(ctx, prm)
if err != nil { if err != nil {
a.log.Error("list containers", zap.Error(err)) resp := a.logAndGetErrorResponse("list containers", err)
return operations.NewListContainersBadRequest().WithPayload("failed to get containers") return operations.NewListContainersBadRequest().WithPayload(resp)
} }
offset := int(*params.Offset) offset := int(*params.Offset)
@ -171,8 +175,8 @@ func (a *API) ListContainer(params operations.ListContainersParams) middleware.R
for _, id := range ids[offset : offset+size] { for _, id := range ids[offset : offset+size] {
baseInfo, err := getContainerBaseInfo(ctx, a.pool, id) baseInfo, err := getContainerBaseInfo(ctx, a.pool, id)
if err != nil { if err != nil {
a.log.Error("get container", zap.String("cid", id.String()), zap.Error(err)) resp := a.logAndGetErrorResponse("get container", err, zap.String("cid", id.String()))
return operations.NewListContainersBadRequest().WithPayload("failed to get container") return operations.NewListContainersBadRequest().WithPayload(resp)
} }
res.Containers = append(res.Containers, baseInfo) res.Containers = append(res.Containers, baseInfo)
} }
@ -189,14 +193,14 @@ func (a *API) DeleteContainer(params operations.DeleteContainerParams, principal
} }
stoken, err := prepareSessionToken(bt, *params.WalletConnect) stoken, err := prepareSessionToken(bt, *params.WalletConnect)
if err != nil { if err != nil {
a.log.Error("failed parse session token", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid session token", err)
return operations.NewDeleteContainerBadRequest().WithPayload(util.NewError(err)) return operations.NewDeleteContainerBadRequest().WithPayload(resp)
} }
cnrID, err := parseContainerID(params.ContainerID) cnrID, err := parseContainerID(params.ContainerID)
if err != nil { if err != nil {
a.log.Error("failed get container id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid container id", err)
return operations.NewDeleteContainerBadRequest().WithPayload(util.NewError(err)) return operations.NewDeleteContainerBadRequest().WithPayload(resp)
} }
var prm pool.PrmContainerDelete var prm pool.PrmContainerDelete
@ -204,8 +208,8 @@ func (a *API) DeleteContainer(params operations.DeleteContainerParams, principal
prm.SetSessionToken(*stoken) prm.SetSessionToken(*stoken)
if err = a.pool.DeleteContainer(params.HTTPRequest.Context(), prm); err != nil { if err = a.pool.DeleteContainer(params.HTTPRequest.Context(), prm); err != nil {
a.log.Error("failed delete container", zap.String("container", params.ContainerID), zap.Error(err)) resp := a.logAndGetErrorResponse("delete container", err, zap.String("container", params.ContainerID))
return operations.NewDeleteContainerBadRequest().WithPayload(util.NewError(err)) return operations.NewDeleteContainerBadRequest().WithPayload(resp)
} }
return operations.NewDeleteContainerOK().WithPayload(util.NewSuccessResponse()) return operations.NewDeleteContainerOK().WithPayload(util.NewSuccessResponse())
@ -280,7 +284,7 @@ func getContainerEACL(ctx context.Context, p *pool.Pool, cnrID *cid.ID) (*models
table, err := p.GetEACL(ctx, prm) table, err := p.GetEACL(ctx, prm)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("get eacl: %w", err)
} }
tableResp := &models.Eacl{ tableResp := &models.Eacl{
@ -397,7 +401,3 @@ func prepareSessionToken(bt *BearerToken, isWalletConnect bool) (*session.Token,
return stoken, err return stoken, err
} }
func wrapError(err error) middleware.Responder {
return operations.NewPutContainerBadRequest().WithPayload(models.Error(err.Error()))
}

View file

@ -5,6 +5,7 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io" "io"
"strings" "strings"
@ -33,18 +34,20 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect) btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect)
if err != nil { if err != nil {
return errorResponse.WithPayload(models.Error(err.Error())) resp := a.logAndGetErrorResponse("invalid bearer token", err)
return errorResponse.WithPayload(resp)
} }
var cnrID cid.ID var cnrID cid.ID
if err = cnrID.Parse(*params.Object.ContainerID); err != nil { if err = cnrID.Parse(*params.Object.ContainerID); err != nil {
a.log.Error("invalid container id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid container id", err)
return errorResponse.WithPayload("invalid container id") return errorResponse.WithPayload(resp)
} }
payload, err := base64.StdEncoding.DecodeString(params.Object.Payload) payload, err := base64.StdEncoding.DecodeString(params.Object.Payload)
if err != nil { if err != nil {
return errorResponse.WithPayload(models.Error(err.Error())) resp := a.logAndGetErrorResponse("invalid object payload", err)
return errorResponse.WithPayload(resp)
} }
prm := PrmAttributes{ prm := PrmAttributes{
@ -53,7 +56,8 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
} }
attributes, err := GetObjectAttributes(ctx, a.pool, params.Object.Attributes, prm) attributes, err := GetObjectAttributes(ctx, a.pool, params.Object.Attributes, prm)
if err != nil { if err != nil {
return errorResponse.WithPayload(models.Error(err.Error())) resp := a.logAndGetErrorResponse("failed to get object attributes", err)
return errorResponse.WithPayload(resp)
} }
obj := object.New() obj := object.New()
@ -68,8 +72,8 @@ func (a *API) PutObjects(params operations.PutObjectParams, principal *models.Pr
objID, err := a.pool.PutObject(ctx, prmPut) objID, err := a.pool.PutObject(ctx, prmPut)
if err != nil { if err != nil {
a.log.Error("put object", zap.Error(err)) resp := a.logAndGetErrorResponse("put object", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
var resp models.Address var resp models.Address
@ -86,14 +90,14 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
addr, err := parseAddress(params.ContainerID, params.ObjectID) addr, err := parseAddress(params.ContainerID, params.ObjectID)
if err != nil { if err != nil {
a.log.Error("invalid address", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid address", err)
return errorResponse.WithPayload("invalid address") return errorResponse.WithPayload(resp)
} }
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect) btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect)
if err != nil { if err != nil {
a.log.Error("get bearer token", zap.Error(err)) resp := a.logAndGetErrorResponse("get bearer token", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
var prm pool.PrmObjectHead var prm pool.PrmObjectHead
@ -102,8 +106,8 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
objInfo, err := a.pool.HeadObject(ctx, prm) objInfo, err := a.pool.HeadObject(ctx, prm)
if err != nil { if err != nil {
a.log.Error("head object", zap.Error(err)) resp := a.logAndGetErrorResponse("head object", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
var resp models.ObjectInfo var resp models.ObjectInfo
@ -128,8 +132,8 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
var offset, length uint64 var offset, length uint64
if params.RangeOffset != nil || params.RangeLength != nil { if params.RangeOffset != nil || params.RangeLength != nil {
if params.RangeOffset == nil || params.RangeLength == nil { if params.RangeOffset == nil || params.RangeLength == nil {
a.log.Error("both offset and length must be provided") errResp := a.logAndGetErrorResponse("invalid range param", errors.New("both offset and length musded"))
return errorResponse.WithPayload(util.NewError(fmt.Errorf("both offset and length must be provided"))) return errorResponse.WithPayload(errResp)
} }
offset = uint64(*params.RangeOffset) offset = uint64(*params.RangeOffset)
length = uint64(*params.RangeLength) length = uint64(*params.RangeLength)
@ -145,8 +149,8 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
rangeRes, err := a.pool.ObjectRange(ctx, prmRange) rangeRes, err := a.pool.ObjectRange(ctx, prmRange)
if err != nil { if err != nil {
a.log.Error("range object", zap.Error(err)) errResp := a.logAndGetErrorResponse("range object", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(errResp)
} }
defer func() { defer func() {
@ -159,12 +163,12 @@ func (a *API) GetObjectInfo(params operations.GetObjectInfoParams, principal *mo
encoder := base64.NewEncoder(base64.StdEncoding, sb) encoder := base64.NewEncoder(base64.StdEncoding, sb)
payloadSize, err := io.Copy(encoder, rangeRes) payloadSize, err := io.Copy(encoder, rangeRes)
if err != nil { if err != nil {
a.log.Error("encode object payload", zap.Error(err)) errResp := a.logAndGetErrorResponse("encode object payload", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(errResp)
} }
if err = encoder.Close(); err != nil { if err = encoder.Close(); err != nil {
a.log.Error("close encoder", zap.Error(err)) errResp := a.logAndGetErrorResponse("close encoder", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(errResp)
} }
resp.Payload = sb.String() resp.Payload = sb.String()
@ -180,14 +184,14 @@ func (a *API) DeleteObject(params operations.DeleteObjectParams, principal *mode
addr, err := parseAddress(params.ContainerID, params.ObjectID) addr, err := parseAddress(params.ContainerID, params.ObjectID)
if err != nil { if err != nil {
a.log.Error("invalid address", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid address", err)
return errorResponse.WithPayload("invalid address") return errorResponse.WithPayload(resp)
} }
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect) btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect)
if err != nil { if err != nil {
a.log.Error("failed to get bearer token", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to get bearer token", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
var prm pool.PrmObjectDelete var prm pool.PrmObjectDelete
@ -195,8 +199,8 @@ func (a *API) DeleteObject(params operations.DeleteObjectParams, principal *mode
prm.UseBearer(btoken) prm.UseBearer(btoken)
if err = a.pool.DeleteObject(ctx, prm); err != nil { if err = a.pool.DeleteObject(ctx, prm); err != nil {
a.log.Error("failed to delete object", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to delete object", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
return operations.NewDeleteObjectOK().WithPayload(util.NewSuccessResponse()) return operations.NewDeleteObjectOK().WithPayload(util.NewSuccessResponse())
@ -209,20 +213,20 @@ func (a *API) SearchObjects(params operations.SearchObjectsParams, principal *mo
var cnrID cid.ID var cnrID cid.ID
if err := cnrID.Parse(params.ContainerID); err != nil { if err := cnrID.Parse(params.ContainerID); err != nil {
a.log.Error("invalid container id", zap.Error(err)) resp := a.logAndGetErrorResponse("invalid container id", err)
return errorResponse.WithPayload("invalid container id") return errorResponse.WithPayload(resp)
} }
btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect) btoken, err := getBearerToken(principal, params.XBearerSignature, params.XBearerSignatureKey, *params.WalletConnect)
if err != nil { if err != nil {
a.log.Error("failed to get bearer token", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to get bearer token", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
filters, err := util.ToNativeFilters(params.SearchFilters) filters, err := util.ToNativeFilters(params.SearchFilters)
if err != nil { if err != nil {
a.log.Error("failed to transform to native", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to transform to native", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
var prm pool.PrmObjectSearch var prm pool.PrmObjectSearch
@ -232,8 +236,8 @@ func (a *API) SearchObjects(params operations.SearchObjectsParams, principal *mo
resSearch, err := a.pool.SearchObjects(ctx, prm) resSearch, err := a.pool.SearchObjects(ctx, prm)
if err != nil { if err != nil {
a.log.Error("failed to search objects", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to search objects", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
offset := int(*params.Offset) offset := int(*params.Offset)
@ -262,8 +266,8 @@ func (a *API) SearchObjects(params operations.SearchObjectsParams, principal *mo
err = iterateErr err = iterateErr
} }
if err != nil { if err != nil {
a.log.Error("failed to search objects", zap.Error(err)) resp := a.logAndGetErrorResponse("failed to search objects", err)
return errorResponse.WithPayload(util.NewError(err)) return errorResponse.WithPayload(resp)
} }
list := &models.ObjectList{ list := &models.ObjectList{

View file

@ -2,10 +2,12 @@ package util
import ( import (
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session" sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-rest-gw/gen/models" "github.com/nspcc-dev/neofs-rest-gw/gen/models"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/eacl" "github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
@ -456,3 +458,26 @@ func NewSuccessResponse() *models.SuccessResponse {
Success: NewBool(true), Success: NewBool(true),
} }
} }
// NewErrorResponse forms model.ErrorResponse.
func NewErrorResponse(err error) *models.ErrorResponse {
var code int64
t := models.ErrorTypeGW
if status, ok := unwrapErr(err).(apistatus.StatusV2); ok {
code = int64(status.ToStatusV2().Code())
t = models.ErrorTypeAPI
}
return &models.ErrorResponse{
Code: code,
Message: NewString(err.Error()),
Type: models.NewErrorType(t),
}
}
func unwrapErr(err error) error {
for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) {
err = e
}
return err
}

View file

@ -0,0 +1,27 @@
package util
import (
"encoding/json"
"errors"
"fmt"
"testing"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/stretchr/testify/require"
)
func TestErrors(t *testing.T) {
apiErr := fmt.Errorf("some context: %w", apistatus.ContainerNotFound{})
resp := NewErrorResponse(apiErr)
data, err := json.Marshal(resp)
require.NoError(t, err)
require.Equal(t, `{"code":3072,"message":"some context: status: code = 3072","type":"API"}`, string(data))
gwErr := fmt.Errorf("some context: %w", errors.New("sanity check error"))
resp = NewErrorResponse(gwErr)
data, err = json.Marshal(resp)
require.NoError(t, err)
require.Equal(t, `{"message":"some context: sanity check error","type":"GW"}`, string(data))
}

View file

@ -91,7 +91,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/objects: /objects:
parameters: parameters:
@ -120,7 +120,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/objects/{containerId}/search: /objects/{containerId}/search:
parameters: parameters:
@ -159,7 +159,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/objects/{containerId}/{objectId}: /objects/{containerId}/{objectId}:
parameters: parameters:
@ -197,7 +197,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
delete: delete:
operationId: deleteObject operationId: deleteObject
summary: Remove object from NeoFS summary: Remove object from NeoFS
@ -209,7 +209,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/containers: /containers:
put: put:
@ -256,7 +256,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
get: get:
operationId: listContainers operationId: listContainers
summary: Get list of containers summary: Get list of containers
@ -288,7 +288,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/containers/{containerId}: /containers/{containerId}:
parameters: parameters:
@ -305,7 +305,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
delete: delete:
operationId: deleteContainer operationId: deleteContainer
summary: Delete container by id summary: Delete container by id
@ -321,7 +321,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
/containers/{containerId}/eacl: /containers/{containerId}/eacl:
parameters: parameters:
- $ref: '#/parameters/containerId' - $ref: '#/parameters/containerId'
@ -346,7 +346,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
get: get:
operationId: getContainerEACL operationId: getContainerEACL
summary: Get container EACL by id summary: Get container EACL by id
@ -359,7 +359,7 @@ paths:
400: 400:
description: Bad request description: Bad request
schema: schema:
$ref: '#/definitions/Error' $ref: '#/definitions/ErrorResponse'
definitions: definitions:
Bearer: Bearer:
@ -710,8 +710,23 @@ definitions:
- value - value
Principal: Principal:
type: string type: string
Error: ErrorType:
type: string type: string
enum:
- GW
- API
ErrorResponse:
type: object
properties:
type:
$ref: '#/definitions/ErrorType'
code:
type: integer
message:
type: string
required:
- type
- message
SuccessResponse: SuccessResponse:
type: object type: object
properties: properties: