github.com/safedep/dry@v0.0.0-20241016050132-a15651f0548b/errors/apierror.go (about)

     1  package errors
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	goerrors "errors"
     9  
    10  	"github.com/safedep/dry/api"
    11  	"github.com/safedep/dry/utils"
    12  )
    13  
    14  type apiErrWrap struct {
    15  	apiErr *api.ApiError
    16  }
    17  
    18  // AsApiError safely performs type conversion
    19  // or build a generic Api Error object with message
    20  func AsApiError(err error) (*apiErrWrap, bool) {
    21  	if aErr, ok := err.(*apiErrWrap); ok {
    22  		return aErr, true
    23  	}
    24  
    25  	error_type := api.ApiErrorTypeInternalError
    26  	error_code := api.ApiErrorCodeAppGenericError
    27  	error_msg := err.Error()
    28  
    29  	return &apiErrWrap{
    30  		apiErr: &api.ApiError{
    31  			Type:    &error_type,
    32  			Code:    &error_code,
    33  			Message: &error_msg,
    34  		},
    35  	}, false
    36  }
    37  
    38  func BuildApiError(errType api.ApiErrorType, errCode api.ApiErrorCode,
    39  	message string) *apiErrWrap {
    40  	return &apiErrWrap{
    41  		apiErr: &api.ApiError{
    42  			Type:    &errType,
    43  			Code:    &errCode,
    44  			Message: &message,
    45  		},
    46  	}
    47  }
    48  
    49  func UnmarshalApiError(body []byte) (*apiErrWrap, bool) {
    50  	apiErr := api.ApiError{}
    51  	err := json.Unmarshal(body, &apiErr)
    52  	if err != nil {
    53  		return AsApiError(err)
    54  	}
    55  
    56  	if (apiErr.Type == nil) || (apiErr.Code == nil) {
    57  		return AsApiError(goerrors.New("invalid API error model"))
    58  	}
    59  
    60  	return &apiErrWrap{
    61  		apiErr: &apiErr,
    62  	}, true
    63  }
    64  
    65  func (err *apiErrWrap) AddParam(key, val string) *apiErrWrap {
    66  	if err.apiErr.Params == nil {
    67  		err.apiErr.Params = &api.ApiError_Params{}
    68  	}
    69  
    70  	err.apiErr.Params.Set(key, struct {
    71  		Key   *string `json:"key,omitempty"`
    72  		Value *string `json:"value,omitempty"`
    73  	}{
    74  		Key:   &key,
    75  		Value: &val,
    76  	})
    77  
    78  	return err
    79  }
    80  
    81  func (err *apiErrWrap) Error() string {
    82  	params := "[]"
    83  	if err.apiErr.Params != nil {
    84  		params = "["
    85  		for key, value := range err.apiErr.Params.AdditionalProperties {
    86  			params = params + " "
    87  			params = params + fmt.Sprintf("%s:\"%s\"", key, utils.SafelyGetValue(value.Value))
    88  		}
    89  		params = params + " ]"
    90  	}
    91  
    92  	return fmt.Sprintf("ApiError: Type=%s Code=%s Message=%s Params=%s",
    93  		*err.apiErr.Type, *err.apiErr.Code, *err.apiErr.Message, params)
    94  }
    95  
    96  func (err *apiErrWrap) HttpCode() int {
    97  	switch *err.apiErr.Code {
    98  	case api.ApiErrorCodeAppPackageVersionNotFound:
    99  		return http.StatusNotFound
   100  	default:
   101  		return http.StatusInternalServerError
   102  	}
   103  }
   104  
   105  // Retriable returns true if the error indicates that the client should
   106  // retry the request
   107  func (err *apiErrWrap) Retriable() bool {
   108  	return false
   109  }
   110  
   111  func (err *apiErrWrap) ApiError() *api.ApiError {
   112  	return err.apiErr
   113  }