github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/edgeworkers/errors.go (about)

     1  package edgeworkers
     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 an edgeworkers error implementation
    15  	// For details on possible error types, refer to: https://techdocs.akamai.com/edgeworkers/reference/api-errors
    16  	Error struct {
    17  		Type             string     `json:"type,omitempty"`
    18  		Title            string     `json:"title,omitempty"`
    19  		Detail           string     `json:"detail,omitempty"`
    20  		Instance         string     `json:"instance,omitempty"`
    21  		Status           int        `json:"status,omitempty"`
    22  		ErrorCode        string     `json:"errorCode,omitempty"`
    23  		Method           string     `json:"method,omitempty"`
    24  		ServerIP         string     `json:"serverIp,omitempty"`
    25  		ClientIP         string     `json:"clientIp,omitempty"`
    26  		RequestID        string     `json:"requestId,omitempty"`
    27  		RequestTime      string     `json:"requestTime,omitempty"`
    28  		AuthzRealm       string     `json:"authzRealm,omitempty"`
    29  		AdditionalDetail Additional `json:"additionalDetail,omitempty"`
    30  	}
    31  
    32  	// Additional holds request_id for edgekv errors
    33  	Additional struct {
    34  		RequestID string `json:"requestId,omitempty"`
    35  	}
    36  )
    37  
    38  const (
    39  	errorCodeNotFound                  = "EKV_9000"
    40  	errorCodeVersionIsBeingDeactivated = "EW1031"
    41  	errorCodeVersionAlreadyDeactivated = "EW1032"
    42  )
    43  
    44  var (
    45  	// ErrNotFound is returned when edgeKV resource does not exist
    46  	ErrNotFound = errors.New("specified edgeKV resource does not exist")
    47  	// ErrVersionBeingDeactivated is returned when edgeworkers version is currently being deactivated
    48  	ErrVersionBeingDeactivated = errors.New("version is being deactivated")
    49  	// ErrVersionAlreadyDeactivated is returned when edgeworkers version is already deactivated
    50  	ErrVersionAlreadyDeactivated = errors.New("version is already deactivated")
    51  )
    52  
    53  // Error parses an error from the response
    54  func (e *edgeworkers) Error(r *http.Response) error {
    55  	var result Error
    56  	var body []byte
    57  	body, err := ioutil.ReadAll(r.Body)
    58  	if err != nil {
    59  		e.Log(r.Request.Context()).Errorf("reading error response body: %s", err)
    60  		result.Status = r.StatusCode
    61  		result.Title = "Failed to read error body"
    62  		result.Detail = err.Error()
    63  		return &result
    64  	}
    65  
    66  	if err := json.Unmarshal(body, &result); err != nil {
    67  		e.Log(r.Request.Context()).Errorf("could not unmarshal API error: %s", err)
    68  		result.Title = fmt.Sprintf("Failed to unmarshal error body. Edgeworkers API failed. Check details for more information.")
    69  		result.Detail = errs.UnescapeContent(string(body))
    70  		result.Status = r.StatusCode
    71  	}
    72  	return &result
    73  }
    74  
    75  func (e *Error) Error() string {
    76  	msg, err := json.MarshalIndent(e, "", "\t")
    77  	if err != nil {
    78  		return fmt.Sprintf("error marshaling API error: %s", err)
    79  	}
    80  	return fmt.Sprintf("API error: \n%s", msg)
    81  }
    82  
    83  // Is handles error comparisons
    84  func (e *Error) Is(target error) bool {
    85  	if errors.Is(target, ErrNotFound) {
    86  		return e.Status == http.StatusNotFound && e.ErrorCode == errorCodeNotFound
    87  	}
    88  	if errors.Is(target, ErrVersionBeingDeactivated) {
    89  		return e.ErrorCode == errorCodeVersionIsBeingDeactivated
    90  	}
    91  	if errors.Is(target, ErrVersionAlreadyDeactivated) {
    92  		return e.ErrorCode == errorCodeVersionAlreadyDeactivated
    93  	}
    94  
    95  	var t *Error
    96  	if !errors.As(target, &t) {
    97  		return false
    98  	}
    99  
   100  	if e == t {
   101  		return true
   102  	}
   103  
   104  	if e.Status != t.Status {
   105  		return false
   106  	}
   107  
   108  	return e.Error() == t.Error()
   109  }