package api import ( "encoding/json" "strings" ) type ResponseCommon struct { RequestID string `read:"request_id"` } type RawResponse struct { ResponseCommon `read:",inline"` Result json.RawMessage `read:"result,omitempty"` Results json.RawMessage `read:"results,omitempty"` } const ( ErrorTypeParamaterError string = "ParameterError" ErrorTypeNotFound string = "NotFound" ErrorTypeTooManyRequests string = "TooManyRequests" ErrorTypeSystemError string = "SystemError" ErrorTypeGatewayTimeout string = "GatewayTimeout" ) type BadResponse struct { ResponseCommon `read:",inline"` StatusCode int `read:"-"` ErrorType string `read:"error_type"` ErrorMessage string `read:"error_message"` ErrorDetails ErrorDetails `read:"error_details"` } func (r *BadResponse) Error() string { if r.ErrorType == ErrorTypeParamaterError { if r.IsAuthError() { return "Auth error" } } errorDetail := "" if len(r.ErrorDetails) > 0 { errorDetail = " Detail: " + r.ErrorDetails.Error() } return "ErrorType: " + r.ErrorType + " Message: " + r.ErrorMessage + errorDetail } func (r *BadResponse) IsStatusCode(code int) bool { return r.StatusCode == code } func (r *BadResponse) IsErrType(name string) bool { return r.ErrorType == name } func (r *BadResponse) IsErrMsg(msg string) bool { return r.ErrorMessage == msg } func (r *BadResponse) IsErrorCode(code string) (bool, string) { for _, errDetail := range r.ErrorDetails { if errDetail.Code == code { return true, errDetail.Attribute } } return false, "" } func (r *BadResponse) IsErrorCodeAttribute(code string, attribute string) bool { for _, errDetail := range r.ErrorDetails { if errDetail.Code == code && errDetail.Attribute == attribute { return true } } return false } func (r *BadResponse) IsAuthError() bool { if r.IsStatusCode(400) && r.IsErrType(ErrorTypeParamaterError) && r.IsErrorCodeAttribute("invalid", "access_token") { return true } return false } func (r *BadResponse) IsRequestFormatError() bool { if r.IsStatusCode(400) && r.IsErrType(ErrorTypeParamaterError) && r.IsErrMsg("JSON parse error occurred.") { return true } return false } func (r *BadResponse) IsParameterError() bool { if r.IsStatusCode(400) && r.IsErrType(ErrorTypeParamaterError) && !r.IsAuthError() && !r.IsRequestFormatError() { return true } return false } func (r *BadResponse) IsNotFound() bool { return r.IsStatusCode(404) } func (r *BadResponse) IsTooManyRequests() bool { return r.IsStatusCode(429) } func (r *BadResponse) IsSystemError() bool { return r.IsStatusCode(500) } func (r *BadResponse) IsGatewayTimeout() bool { return r.IsStatusCode(504) } func (r *BadResponse) IsInvalidSchema() bool { return r.IsParameterError() && r.IsErrorCodeAttribute("invalid", "schema") } type ErrorDetails []ErrorDetail func (e ErrorDetails) Error() string { res := []string{} for _, detail := range e { res = append(res, detail.Error()) } return strings.Join(res, ", ") } type ErrorDetail struct { Code string `read:"code"` Attribute string `read:"attribute"` } func (e ErrorDetail) Error() string { return e.Code + "=" + e.Attribute } type Count struct { Count int32 `read:"count" json:"-"` } func (c *Count) SetCount(v int32) { c.Count = v } func (c *Count) GetCount() int32 { return c.Count } type AsyncResponse struct { ResponseCommon `read:",inline"` JobsURL string `read:"jobs_url"` }