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  }