github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudwrapper/errors.go (about) 1 package cloudwrapper 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 10 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/errs" 11 ) 12 13 type ( 14 // Error is a cloudwrapper error implementation 15 // For details on possible error types, refer to: https://techdocs.akamai.com/cloud-wrapper/reference/errors 16 Error struct { 17 Type string `json:"type,omitempty"` 18 Title string `json:"title,omitempty"` 19 Instance string `json:"instance"` 20 Status int `json:"status"` 21 Detail string `json:"detail"` 22 Errors []ErrorItem `json:"errors"` 23 Method string `json:"method"` 24 ServerIP string `json:"serverIp"` 25 ClientIP string `json:"clientIp"` 26 RequestID string `json:"requestId"` 27 RequestTime string `json:"requestTime"` 28 } 29 30 // ErrorItem is a cloud wrapper error's item 31 ErrorItem struct { 32 Type string `json:"type"` 33 Title string `json:"title"` 34 Detail string `json:"detail"` 35 IllegalValue any `json:"illegalValue"` 36 IllegalParameter string `json:"illegalParameter"` 37 } 38 ) 39 40 const ( 41 configurationNotFoundType = "/cloud-wrapper/error-types/not-found" 42 deletionNotAllowedType = "/cloud-wrapper/error-types/forbidden" 43 ) 44 45 var ( 46 // ErrConfigurationNotFound is returned when configuration was not found 47 ErrConfigurationNotFound = errors.New("configuration not found") 48 // ErrDeletionNotAllowed is returned when user has insufficient permissions to delete configuration 49 ErrDeletionNotAllowed = errors.New("deletion not allowed") 50 ) 51 52 // Error parses an error from the response 53 func (c *cloudwrapper) Error(r *http.Response) error { 54 var result Error 55 var body []byte 56 body, err := ioutil.ReadAll(r.Body) 57 if err != nil { 58 c.Log(r.Request.Context()).Errorf("reading error response body: %s", err) 59 result.Status = r.StatusCode 60 result.Title = "Failed to read error body" 61 result.Detail = err.Error() 62 return &result 63 } 64 65 if err = json.Unmarshal(body, &result); err != nil { 66 c.Log(r.Request.Context()).Errorf("could not unmarshal API error: %s", err) 67 result.Title = "Failed to unmarshal error body. Cloud Wrapper API failed. Check details for more information." 68 result.Detail = errs.UnescapeContent(string(body)) 69 result.Status = r.StatusCode 70 } 71 return &result 72 } 73 74 func (e *Error) Error() string { 75 msg, err := json.MarshalIndent(e, "", "\t") 76 if err != nil { 77 return fmt.Sprintf("error marshaling API error: %s", err) 78 } 79 return fmt.Sprintf("API error: \n%s", msg) 80 } 81 82 // Is handles error comparisons 83 func (e *Error) Is(target error) bool { 84 if errors.Is(target, ErrConfigurationNotFound) { 85 return e.Status == http.StatusNotFound && e.Type == configurationNotFoundType 86 } 87 if errors.Is(target, ErrDeletionNotAllowed) { 88 return e.Status == http.StatusForbidden && e.Type == deletionNotAllowedType 89 } 90 91 var t *Error 92 if !errors.As(target, &t) { 93 return false 94 } 95 96 if e == t { 97 return true 98 } 99 100 if e.Status != t.Status { 101 return false 102 } 103 104 return e.Error() == t.Error() 105 }