Skip to content

Commit

Permalink
Add files previously hidden within autogenerated code (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ricardo-Osorio authored Feb 9, 2022
1 parent 4acc601 commit 17bedc0
Show file tree
Hide file tree
Showing 2 changed files with 357 additions and 0 deletions.
159 changes: 159 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package storageos

import (
"fmt"
"net/http"

api "github.com/storageos/go-api/autogenerated"
)

// badRequestError indicates that the request made by the client is invalid.
type badRequestError struct {
msg string
}

func (e badRequestError) Error() string {
if e.msg == "" {
return "bad request"
}
return e.msg
}

func NewBadRequestError(msg string) badRequestError {
return badRequestError{
msg: msg,
}
}

// notFoundError indicates that a resource involved in carrying out the API
// request was not found.
type notFoundError struct {
msg string
}

func (e notFoundError) Error() string {
if e.msg == "" {
return "not found"
}
return e.msg
}

func NewNotFoundError(msg string) notFoundError {
return notFoundError{
msg: msg,
}
}

// conflictError indicates that the requested operation could not be carried
// out due to a conflict between the current state and the desired state.
type conflictError struct {
msg string
}

func (e conflictError) Error() string {
if e.msg == "" {
return "conflict"
}
return e.msg
}

func NewConflictError(msg string) conflictError {
return conflictError{
msg: msg,
}
}

type openAPIError struct {
inner api.Error
}

func (e openAPIError) Error() string {
return e.inner.Error
}

// MapAPIError will given err and its corresponding resp attempt to map the
// HTTP error to an application level error.
//
// err is returned as is when any of the following are true:
//
// → resp is nil
// → err is not a GenericOpenAPIError or the unexported openAPIError
//
// Some response codes must be mapped by the caller in order to provide useful
// application level errors:
//
// → http.StatusBadRequest returns a badRequestError, which must have a 1-to-1
// mapping to a context specific application error
// → http.StatusNotFound returns a notFoundError, which must have a 1-to-1
// mapping to a context specific application error
// → http.StatusConflict returns a conflictError which must have a 1-to-1
// mapping to a context specific application error
//
func MapAPIError(err error, resp *http.Response) error {
if resp == nil {
return err
}

var details string
switch v := err.(type) {
case api.GenericOpenAPIError:
switch model := v.Model().(type) {
case api.Error:
details = model.Error
default:
details = string(v.Body())
}
case openAPIError:
details = v.Error()
default:
return err
}

switch resp.StatusCode {

// 4XX
case http.StatusBadRequest:
return NewBadRequestError(details)

case http.StatusUnauthorized:
return NewAuthenticationError(details)

case http.StatusForbidden:
return NewUnauthorisedError(details)

case http.StatusNotFound:
return NewNotFoundError(details)

case http.StatusConflict:
return NewConflictError(details)

case http.StatusPreconditionFailed:
return NewStaleWriteError(details)

case http.StatusUnprocessableEntity:
return NewInvalidStateTransitionError(details)

case http.StatusLocked:
return NewLockedError(details)

// This may need changing to present a friendly error, or it may be done up
// the call stack.
case http.StatusUnavailableForLegalReasons:
return NewLicenceCapabilityError(details)

// 5XX
case http.StatusInternalServerError:
return NewServerError(details)

case http.StatusServiceUnavailable:
return NewStoreError(details)

default:
// If details were obtained from the error, decorate it - even when
// unknown.
if details != "" {
err = fmt.Errorf("%w: %v", err, details)
}
return err
}
}
198 changes: 198 additions & 0 deletions map_errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package storageos

import (
"fmt"
)

// AuthenticationError indicates that the requested operation could not be
// performed for the client due to an issue with the authentication credentials
// provided by the client.
type AuthenticationError struct {
msg string
}

func (e AuthenticationError) Error() string {
if e.msg == "" {
return "authentication error"
}
return e.msg
}

// NewAuthenticationError returns a new AuthenticationError using msg as an
// optional error message if given.
func NewAuthenticationError(msg string) AuthenticationError {
return AuthenticationError{
msg: msg,
}
}

// UnauthorisedError indicates that the requested operation is disallowed
// for the user which the client is authenticated as.
type UnauthorisedError struct {
msg string
}

func (e UnauthorisedError) Error() string {
if e.msg == "" {
return "authenticated user is not authorised to perform that action"
}
return e.msg
}

// NewUnauthorisedError returns a new UnauthorisedError using msg as an
// optional error message if given.
func NewUnauthorisedError(msg string) UnauthorisedError {
return UnauthorisedError{
msg: msg,
}
}

// StaleWriteError indicates that the target resource for the requested
// operation has been concurrently updated, invalidating the request. The client
// should fetch the latest version of the resource before attempting to perform
// another update.
type StaleWriteError struct {
msg string
}

func (e StaleWriteError) Error() string {
if e.msg == "" {
return "stale write attempted"
}
return e.msg
}

// NewStaleWriteError returns a new StaleWriteError using msg as an optional
// error message if given.
func NewStaleWriteError(msg string) StaleWriteError {
return StaleWriteError{
msg: msg,
}
}

// InvalidStateTransitionError indicates that the requested operation cannot
// be performed for the target resource in its current state.
type InvalidStateTransitionError struct {
msg string
}

func (e InvalidStateTransitionError) Error() string {
if e.msg == "" {
return "target resource is in an invalid state for carrying out the request"
}
return e.msg
}

// NewInvalidStateTransitionError returns a new InvalidStateTransitionError
// using msg as an optional error message if given.
func NewInvalidStateTransitionError(msg string) InvalidStateTransitionError {
return InvalidStateTransitionError{
msg: msg,
}
}

// LockedError indicates that the requested operation cannot be performed
// because a lock is held for the target resource.
type LockedError struct {
msg string
}

func (e LockedError) Error() string {
if e.msg == "" {
return "requsted operation cannot be safely completed as the target resource is locked"
}
return e.msg
}

// NewLockedError returns a new LockedError using msg as an optional error
// message if given.
func NewLockedError(msg string) LockedError {
return LockedError{
msg: msg,
}
}

// LicenceCapabilityError indicates that the requested operation cannot be
// carried out due to a licensing issue with the cluster.
type LicenceCapabilityError struct {
msg string
}

func (e LicenceCapabilityError) Error() string {
if e.msg == "" {
return "licence capability error"
}
return e.msg
}

// NewLicenceCapabilityError returns a new LicenceCapabilityError using msg as
// an optional error message if given.
func NewLicenceCapabilityError(msg string) LicenceCapabilityError {
return LicenceCapabilityError{
msg: msg,
}
}

// ServerError indicates that an unrecoverable error occurred while attempting
// to perform the requested operation.
type ServerError struct {
msg string
}

func (e ServerError) Error() string {
if e.msg == "" {
return "server encountered internal error"
}
return e.msg
}

// NewServerError returns a new ServerError using msg as an optional error
// message if given.
func NewServerError(msg string) ServerError {
return ServerError{
msg: msg,
}
}

// StoreError indicates that the requested operation could not be performed due
// to a store outage.
type StoreError struct {
msg string
}

func (e StoreError) Error() string {
if e.msg == "" {
return "server encountered store outage"
}
return e.msg
}

// NewStoreError returns a new StoreError using msg as an optional error
// message if given.
func NewStoreError(msg string) StoreError {
return StoreError{
msg: msg,
}
}

// EncodingError provides a unified error type which transport encoding
// implementations return when given a value that cannot be encoded with the
// target encoding.
type EncodingError struct {
err error
targetType interface{}
value interface{}
}

func (e EncodingError) Error() string {
return fmt.Sprintf("cannot encode %v as %T: %s", e.value, e.targetType, e.err)
}

// NewEncodingError wraps err as an encoding error for value into targetType.
func NewEncodingError(err error, targetType, value interface{}) EncodingError {
return EncodingError{
err: err,
targetType: targetType,
value: value,
}
}

0 comments on commit 17bedc0

Please sign in to comment.