@@ -0,0 +1,49 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// APIError is returned for every non-2xx API response. Validation contains
|
||||
// field-specific messages for 422 responses; Message contains ordinary API
|
||||
// error strings.
|
||||
type APIError struct {
|
||||
StatusCode int
|
||||
Message string
|
||||
Validation map[string]string
|
||||
Body string
|
||||
}
|
||||
|
||||
// Error implements error using the API message or HTTP status.
|
||||
func (e *APIError) Error() string {
|
||||
switch {
|
||||
case e.Message != "":
|
||||
return fmt.Sprintf("gardomatic API: %s (%d)", e.Message, e.StatusCode)
|
||||
case len(e.Validation) != 0:
|
||||
return fmt.Sprintf("gardomatic API: validation failed (%d)", e.StatusCode)
|
||||
default:
|
||||
return fmt.Sprintf("gardomatic API: request failed (%d)", e.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func newAPIError(response *http.Response, body []byte) *APIError {
|
||||
apiError := &APIError{
|
||||
StatusCode: response.StatusCode,
|
||||
Body: strings.TrimSpace(string(body)),
|
||||
}
|
||||
|
||||
var envelope struct {
|
||||
Error json.RawMessage `json:"error"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &envelope); err != nil || len(envelope.Error) == 0 {
|
||||
return apiError
|
||||
}
|
||||
if err := json.Unmarshal(envelope.Error, &apiError.Message); err == nil {
|
||||
return apiError
|
||||
}
|
||||
_ = json.Unmarshal(envelope.Error, &apiError.Validation)
|
||||
return apiError
|
||||
}
|
||||
Reference in New Issue
Block a user