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 }