lego/vendor/github.com/akamai/AkamaiOPEN-edgegrid-golang/client-v1/errors.go
2019-02-04 22:12:03 +01:00

107 lines
3.2 KiB
Go

package client
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/akamai/AkamaiOPEN-edgegrid-golang/jsonhooks-v1"
)
// APIError exposes an Akamai OPEN Edgegrid Error
type APIError struct {
error
Type string `json:"type"`
Title string `json:"title"`
Status int `json:"status"`
Detail string `json:"detail"`
Errors []APIErrorDetail `json:"errors"`
Problems []APIErrorDetail `json:"problems"`
Instance string `json:"instance"`
Method string `json:"method"`
ServerIP string `json:"serverIp"`
ClientIP string `json:"clientIp"`
RequestID string `json:"requestId"`
RequestTime string `json:"requestTime"`
Response *http.Response `json:"-"`
RawBody string `json:"-"`
}
type APIErrorDetail struct {
Type string `json:"type"`
Title string `json:"title"`
Detail string `json:"detail"`
RejectedValue string `json:"rejectedValue"`
}
func (error APIError) Error() string {
var errorDetails string
if len(error.Errors) > 0 {
for _, e := range error.Errors {
errorDetails = fmt.Sprintf("%s \n %s", errorDetails, e)
}
}
if len(error.Problems) > 0 {
for _, e := range error.Problems {
errorDetails = fmt.Sprintf("%s \n %s", errorDetails, e)
}
}
return strings.TrimSpace(fmt.Sprintf("API Error: %d %s %s More Info %s\n %s", error.Status, error.Title, error.Detail, error.Type, errorDetails))
}
// NewAPIError creates a new API error based on a Response,
// or http.Response-like.
func NewAPIError(response *http.Response) APIError {
// TODO: handle this error
body, _ := ioutil.ReadAll(response.Body)
return NewAPIErrorFromBody(response, body)
}
// NewAPIErrorFromBody creates a new API error, allowing you to pass in a body
//
// This function is intended to be used after the body has already been read for
// other purposes.
func NewAPIErrorFromBody(response *http.Response, body []byte) APIError {
error := APIError{}
if err := jsonhooks.Unmarshal(body, &error); err == nil {
error.Status = response.StatusCode
error.Title = response.Status
}
error.Response = response
error.RawBody = string(body)
return error
}
// IsInformational determines if a response was informational (1XX status)
func IsInformational(r *http.Response) bool {
return r.StatusCode > 99 && r.StatusCode < 200
}
// IsSuccess determines if a response was successful (2XX status)
func IsSuccess(r *http.Response) bool {
return r.StatusCode > 199 && r.StatusCode < 300
}
// IsRedirection determines if a response was a redirect (3XX status)
func IsRedirection(r *http.Response) bool {
return r.StatusCode > 299 && r.StatusCode < 400
}
// IsClientError determines if a response was a client error (4XX status)
func IsClientError(r *http.Response) bool {
return r.StatusCode > 399 && r.StatusCode < 500
}
// IsServerError determines if a response was a server error (5XX status)
func IsServerError(r *http.Response) bool {
return r.StatusCode > 499 && r.StatusCode < 600
}
// IsError determines if the response was a client or server error (4XX or 5XX status)
func IsError(r *http.Response) bool {
return r.StatusCode > 399 && r.StatusCode < 600
}