response.go raw

   1  package api
   2  
   3  import (
   4  	"encoding/json"
   5  	"strings"
   6  )
   7  
   8  type ResponseCommon struct {
   9  	RequestID string `read:"request_id"`
  10  }
  11  
  12  type RawResponse struct {
  13  	ResponseCommon `read:",inline"`
  14  	Result         json.RawMessage `read:"result,omitempty"`
  15  	Results        json.RawMessage `read:"results,omitempty"`
  16  }
  17  
  18  const (
  19  	ErrorTypeParamaterError  string = "ParameterError"
  20  	ErrorTypeNotFound        string = "NotFound"
  21  	ErrorTypeTooManyRequests string = "TooManyRequests"
  22  	ErrorTypeSystemError     string = "SystemError"
  23  	ErrorTypeGatewayTimeout  string = "GatewayTimeout"
  24  )
  25  
  26  type BadResponse struct {
  27  	ResponseCommon `read:",inline"`
  28  	StatusCode     int          `read:"-"`
  29  	ErrorType      string       `read:"error_type"`
  30  	ErrorMessage   string       `read:"error_message"`
  31  	ErrorDetails   ErrorDetails `read:"error_details"`
  32  }
  33  
  34  func (r *BadResponse) Error() string {
  35  	if r.ErrorType == ErrorTypeParamaterError {
  36  		if r.IsAuthError() {
  37  			return "Auth error"
  38  		}
  39  	}
  40  	errorDetail := ""
  41  	if len(r.ErrorDetails) > 0 {
  42  		errorDetail = " Detail: " + r.ErrorDetails.Error()
  43  	}
  44  	return "ErrorType: " + r.ErrorType + " Message: " + r.ErrorMessage + errorDetail
  45  }
  46  
  47  func (r *BadResponse) IsStatusCode(code int) bool {
  48  	return r.StatusCode == code
  49  }
  50  
  51  func (r *BadResponse) IsErrType(name string) bool {
  52  	return r.ErrorType == name
  53  }
  54  
  55  func (r *BadResponse) IsErrMsg(msg string) bool {
  56  	return r.ErrorMessage == msg
  57  }
  58  
  59  func (r *BadResponse) IsErrorCode(code string) (bool, string) {
  60  	for _, errDetail := range r.ErrorDetails {
  61  		if errDetail.Code == code {
  62  			return true, errDetail.Attribute
  63  		}
  64  	}
  65  	return false, ""
  66  }
  67  
  68  func (r *BadResponse) IsErrorCodeAttribute(code string, attribute string) bool {
  69  	for _, errDetail := range r.ErrorDetails {
  70  		if errDetail.Code == code && errDetail.Attribute == attribute {
  71  			return true
  72  		}
  73  	}
  74  	return false
  75  }
  76  
  77  func (r *BadResponse) IsAuthError() bool {
  78  	if r.IsStatusCode(400) &&
  79  		r.IsErrType(ErrorTypeParamaterError) &&
  80  		r.IsErrorCodeAttribute("invalid", "access_token") {
  81  		return true
  82  	}
  83  	return false
  84  }
  85  
  86  func (r *BadResponse) IsRequestFormatError() bool {
  87  	if r.IsStatusCode(400) &&
  88  		r.IsErrType(ErrorTypeParamaterError) &&
  89  		r.IsErrMsg("JSON parse error occurred.") {
  90  		return true
  91  	}
  92  	return false
  93  }
  94  
  95  func (r *BadResponse) IsParameterError() bool {
  96  	if r.IsStatusCode(400) &&
  97  		r.IsErrType(ErrorTypeParamaterError) &&
  98  		!r.IsAuthError() &&
  99  		!r.IsRequestFormatError() {
 100  		return true
 101  	}
 102  
 103  	return false
 104  }
 105  
 106  func (r *BadResponse) IsNotFound() bool {
 107  	return r.IsStatusCode(404)
 108  }
 109  
 110  func (r *BadResponse) IsTooManyRequests() bool {
 111  	return r.IsStatusCode(429)
 112  }
 113  
 114  func (r *BadResponse) IsSystemError() bool {
 115  	return r.IsStatusCode(500)
 116  }
 117  
 118  func (r *BadResponse) IsGatewayTimeout() bool {
 119  	return r.IsStatusCode(504)
 120  }
 121  
 122  func (r *BadResponse) IsInvalidSchema() bool {
 123  	return r.IsParameterError() && r.IsErrorCodeAttribute("invalid", "schema")
 124  }
 125  
 126  type ErrorDetails []ErrorDetail
 127  
 128  func (e ErrorDetails) Error() string {
 129  	res := []string{}
 130  	for _, detail := range e {
 131  		res = append(res, detail.Error())
 132  	}
 133  	return strings.Join(res, ", ")
 134  }
 135  
 136  type ErrorDetail struct {
 137  	Code      string `read:"code"`
 138  	Attribute string `read:"attribute"`
 139  }
 140  
 141  func (e ErrorDetail) Error() string {
 142  	return e.Code + "=" + e.Attribute
 143  }
 144  
 145  type Count struct {
 146  	Count int32 `read:"count" json:"-"`
 147  }
 148  
 149  func (c *Count) SetCount(v int32) { c.Count = v }
 150  func (c *Count) GetCount() int32  { return c.Count }
 151  
 152  type AsyncResponse struct {
 153  	ResponseCommon `read:",inline"`
 154  	JobsURL        string `read:"jobs_url"`
 155  }
 156