github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/botman/errors.go (about) 1 package botman 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "strings" 10 11 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/errs" 12 ) 13 14 type ( 15 // Error is a botman error interface. 16 Error struct { 17 Type string `json:"type"` 18 Title string `json:"title"` 19 Detail string `json:"detail"` 20 Errors []Error `json:"errors,omitempty"` 21 StatusCode int `json:"status,omitempty"` 22 } 23 ) 24 25 func (b *botman) Error(r *http.Response) error { 26 var e Error 27 var body []byte 28 29 body, err := ioutil.ReadAll(r.Body) 30 if err != nil { 31 b.Log(r.Request.Context()).Errorf("reading error response body: %s", err) 32 e.StatusCode = r.StatusCode 33 e.Title = "Failed to read error body" 34 e.Detail = err.Error() 35 return &e 36 } 37 38 if err := json.Unmarshal(body, &e); err != nil { 39 b.Log(r.Request.Context()).Errorf("could not unmarshal API error: %s", err) 40 e.Title = "Failed to unmarshal error body. Bot Manager API failed. Check details for more information." 41 e.Detail = errs.UnescapeContent(string(body)) 42 } 43 44 e.StatusCode = r.StatusCode 45 46 return &e 47 } 48 49 // Error returns a string formatted using a given title, type, and detail information. 50 func (e *Error) Error() string { 51 detail := e.Detail 52 if e.Errors != nil && len(e.Errors) > 0 { 53 var childErrorDetails []string 54 for _, err := range e.Errors { 55 childErrorDetails = append(childErrorDetails, err.Detail) 56 } 57 detail += ": [" + strings.Join(childErrorDetails, ", ") + " ]" 58 } 59 return fmt.Sprintf("Title: %s; Type: %s; Detail: %s", e.Title, e.Type, detail) 60 } 61 62 // Is handles error comparisons. 63 func (e *Error) Is(target error) bool { 64 var t *Error 65 if !errors.As(target, &t) { 66 return false 67 } 68 69 if e == t { 70 return true 71 } 72 73 if e.StatusCode != t.StatusCode { 74 return false 75 } 76 77 return e.Error() == t.Error() 78 }