2022-10-25 17:32:46 +03:00
|
|
|
package v1
|
|
|
|
|
|
|
|
import (
|
2022-10-26 14:58:32 +03:00
|
|
|
"bytes"
|
2022-10-25 17:32:46 +03:00
|
|
|
"encoding/json"
|
2022-10-26 10:54:54 +03:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
2022-10-25 17:32:46 +03:00
|
|
|
)
|
|
|
|
|
2022-10-26 18:07:04 +03:00
|
|
|
var defaultErrorMessage = "http client error"
|
2022-10-26 14:58:32 +03:00
|
|
|
var internalServerError = "internal server error"
|
2022-10-26 18:07:04 +03:00
|
|
|
var marshalError = "cannot unmarshal response body"
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// MGErrors contains a list of errors as sent by MessageGateway.
|
2022-10-26 18:07:04 +03:00
|
|
|
type MGErrors struct {
|
|
|
|
Errors []string
|
|
|
|
}
|
2022-10-25 17:32:46 +03:00
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// HTTPClientError is a common error type used in the client.
|
2022-10-27 09:28:07 +03:00
|
|
|
type HTTPClientError struct {
|
2022-10-26 18:07:04 +03:00
|
|
|
ErrorMsg string
|
|
|
|
BaseError error
|
|
|
|
Response io.Reader
|
2022-10-25 17:32:46 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// Unwrap returns underlying error. Its presence usually indicates a problem with the network.
|
2022-10-27 09:28:07 +03:00
|
|
|
func (err *HTTPClientError) Unwrap() error {
|
2022-10-25 17:32:46 +03:00
|
|
|
return err.BaseError
|
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// Error message will contain either an error from MG or underlying error message.
|
2022-10-27 09:28:07 +03:00
|
|
|
func (err *HTTPClientError) Error() string {
|
2022-10-25 17:32:46 +03:00
|
|
|
message := defaultErrorMessage
|
|
|
|
|
|
|
|
if err.BaseError != nil {
|
2022-10-26 18:07:04 +03:00
|
|
|
message = fmt.Sprintf("%s: %s", defaultErrorMessage, err.BaseError.Error())
|
2022-10-27 09:28:07 +03:00
|
|
|
} else if len(err.ErrorMsg) > 0 {
|
2022-10-25 17:32:46 +03:00
|
|
|
message = err.ErrorMsg
|
|
|
|
}
|
|
|
|
|
|
|
|
return message
|
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// NewCriticalHTTPError wraps *http.Client error.
|
2022-10-25 17:32:46 +03:00
|
|
|
func NewCriticalHTTPError(err error) error {
|
2022-10-27 09:28:07 +03:00
|
|
|
return &HTTPClientError{BaseError: err}
|
2022-10-25 17:32:46 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// NewAPIClientError wraps MG error.
|
2022-10-25 17:32:46 +03:00
|
|
|
func NewAPIClientError(responseBody []byte) error {
|
2022-10-26 18:07:04 +03:00
|
|
|
var data MGErrors
|
2022-10-25 17:32:46 +03:00
|
|
|
var message string
|
|
|
|
|
|
|
|
if len(responseBody) == 0 {
|
|
|
|
message = internalServerError
|
|
|
|
} else {
|
2022-10-26 18:07:04 +03:00
|
|
|
err := json.Unmarshal(responseBody, &data)
|
2022-10-25 17:32:46 +03:00
|
|
|
|
2022-10-26 18:07:04 +03:00
|
|
|
if err != nil {
|
|
|
|
message = marshalError
|
|
|
|
} else if len(data.Errors) > 0 {
|
|
|
|
message = data.Errors[0]
|
|
|
|
}
|
2022-10-25 17:32:46 +03:00
|
|
|
}
|
|
|
|
|
2022-10-27 09:28:07 +03:00
|
|
|
return &HTTPClientError{ErrorMsg: message}
|
2022-10-26 10:54:54 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// NewServerError wraps an unexpected API error (e.g. 5xx).
|
2022-10-26 10:54:54 +03:00
|
|
|
func NewServerError(response *http.Response) error {
|
2022-10-27 09:28:07 +03:00
|
|
|
var serverError *HTTPClientError
|
2022-10-26 10:54:54 +03:00
|
|
|
|
2022-10-26 18:07:04 +03:00
|
|
|
body, _ := buildLimitedRawResponse(response)
|
|
|
|
err := NewAPIClientError(body)
|
|
|
|
|
|
|
|
if errors.As(err, &serverError) && len(body) > 0 {
|
|
|
|
serverError.Response = bytes.NewBuffer(body)
|
2022-10-26 10:54:54 +03:00
|
|
|
return serverError
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
2023-12-29 11:24:23 +03:00
|
|
|
|
|
|
|
func AsClientError(err error) *HTTPClientError {
|
|
|
|
for {
|
2023-12-29 11:30:09 +03:00
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2023-12-29 11:46:18 +03:00
|
|
|
if typed, ok := err.(*HTTPClientError); ok { //nolint:errorlint
|
2023-12-29 11:30:09 +03:00
|
|
|
return typed
|
|
|
|
}
|
|
|
|
err = errors.Unwrap(err)
|
2023-12-29 11:24:23 +03:00
|
|
|
}
|
|
|
|
}
|