github.com/akamai/AkamaiOPEN-edgegrid-golang/v4@v4.1.0/pkg/papi/errors.go (about) 1 package papi 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 ) 10 11 type ( 12 // Error is a papi error interface 13 Error struct { 14 Type string `json:"type"` 15 Title string `json:"title,omitempty"` 16 Detail string `json:"detail"` 17 Instance string `json:"instance,omitempty"` 18 BehaviorName string `json:"behaviorName,omitempty"` 19 ErrorLocation string `json:"errorLocation,omitempty"` 20 StatusCode int `json:"statusCode,omitempty"` 21 Errors json.RawMessage `json:"errors,omitempty"` 22 Warnings json.RawMessage `json:"warnings,omitempty"` 23 LimitKey string `json:"limitKey,omitempty"` 24 Limit *int `json:"limit,omitempty"` 25 Remaining *int `json:"remaining,omitempty"` 26 } 27 ) 28 29 // Error parses an error from the response 30 func (p *papi) Error(r *http.Response) error { 31 var e Error 32 33 var body []byte 34 35 body, err := ioutil.ReadAll(r.Body) 36 if err != nil { 37 p.Log(r.Request.Context()).Errorf("reading error response body: %s", err) 38 e.StatusCode = r.StatusCode 39 e.Title = fmt.Sprintf("Failed to read error body") 40 e.Detail = err.Error() 41 return &e 42 } 43 44 if err := json.Unmarshal(body, &e); err != nil { 45 p.Log(r.Request.Context()).Errorf("could not unmarshal API error: %s", err) 46 e.Title = fmt.Sprintf("Failed to unmarshal error body") 47 e.Detail = err.Error() 48 } 49 50 e.StatusCode = r.StatusCode 51 52 return &e 53 } 54 55 func (e *Error) Error() string { 56 msg, err := json.MarshalIndent(e, "", "\t") 57 if err != nil { 58 return fmt.Sprintf("error marshaling API error: %s", err) 59 } 60 return fmt.Sprintf("API error: \n%s", msg) 61 } 62 63 // Is handles error comparisons 64 func (e *Error) Is(target error) bool { 65 if errors.Is(target, ErrSBDNotEnabled) { 66 return e.isErrSBDNotEnabled() 67 } 68 if errors.Is(target, ErrDefaultCertLimitReached) { 69 return e.isErrDefaultCertLimitReached() 70 } 71 72 var t *Error 73 if !errors.As(target, &t) { 74 return false 75 } 76 77 if e == t { 78 return true 79 } 80 81 if e.StatusCode != t.StatusCode { 82 return false 83 } 84 85 return e.Error() == t.Error() 86 } 87 88 func (e *Error) isErrSBDNotEnabled() bool { 89 return e.StatusCode == http.StatusForbidden && e.Type == "https://problems.luna.akamaiapis.net/papi/v0/property-version-hostname/default-cert-provisioning-unavailable" 90 } 91 92 func (e *Error) isErrDefaultCertLimitReached() bool { 93 return e.StatusCode == http.StatusTooManyRequests && e.LimitKey == "DEFAULT_CERTS_PER_CONTRACT" && e.Remaining != nil && *e.Remaining == 0 94 }