github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/hapi/errors.go (about) 1 package hapi 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 hapi error interface 15 Error struct { 16 Type string `json:"type"` 17 Title string `json:"title"` 18 Detail string `json:"detail"` 19 Instance string `json:"instance,omitempty"` 20 RequestInstance string `json:"requestInstance,omitempty"` 21 Method string `json:"method,omitempty"` 22 RequestTime string `json:"requestTime,omitempty"` 23 BehaviorName string `json:"behaviorName,omitempty"` 24 ErrorLocation string `json:"errorLocation,omitempty"` 25 Status int `json:"status,omitempty"` 26 DomainPrefix string `json:"domainPrefix,omitempty"` 27 DomainSuffix string `json:"domainSuffix,omitempty"` 28 Errors []ErrorItem `json:"errors,omitempty"` 29 } 30 31 // ErrorItem represents single error item 32 ErrorItem struct { 33 Key string `json:"key,omitempty"` 34 Value string `json:"value,omitempty"` 35 } 36 ) 37 38 // Error parses an error from the response 39 func (h *hapi) Error(r *http.Response) error { 40 var e Error 41 42 var body []byte 43 44 body, err := ioutil.ReadAll(r.Body) 45 if err != nil { 46 h.Log(r.Request.Context()).Errorf("reading error response body: %s", err) 47 e.Status = r.StatusCode 48 e.Title = fmt.Sprintf("Failed to read error body") 49 e.Detail = err.Error() 50 return &e 51 } 52 53 if err := json.Unmarshal(body, &e); err != nil { 54 h.Log(r.Request.Context()).Errorf("could not unmarshal API error: %s", err) 55 e.Title = fmt.Sprintf("Failed to unmarshal error body. HAPI API failed. Check details for more information.") 56 e.Detail = errs.UnescapeContent(string(body)) 57 } 58 59 e.Status = r.StatusCode 60 61 return &e 62 } 63 64 func (e *Error) Error() string { 65 msg, err := json.MarshalIndent(e, "", "\t") 66 if err != nil { 67 return fmt.Sprintf("error marshaling API error: %s", err) 68 } 69 return fmt.Sprintf("API error: \n%s", msg) 70 } 71 72 // Is handles error comparisons 73 func (e *Error) Is(target error) bool { 74 var t *Error 75 if !errors.As(target, &t) { 76 return false 77 } 78 79 if e == t { 80 return true 81 } 82 83 if e.Status != t.Status { 84 return false 85 } 86 87 return e.Error() == t.Error() 88 }