141 lines
3.2 KiB
Go
141 lines
3.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
)
|
|
|
|
// Response represents an API response
|
|
type Response struct {
|
|
Result json.RawMessage `json:"result"`
|
|
Error string `json:"error,omitempty"`
|
|
ErrorDescription string `json:"errorDescription,omitempty"`
|
|
}
|
|
|
|
// GetResult returns the result as raw JSON
|
|
func (r *Response) GetResult() json.RawMessage {
|
|
return r.Result
|
|
}
|
|
|
|
// GetError returns the error message
|
|
func (r *Response) GetError() string {
|
|
if r.Error != "" {
|
|
return r.Error
|
|
}
|
|
if r.ErrorDescription != "" {
|
|
return r.ErrorDescription
|
|
}
|
|
return "Unknown error"
|
|
}
|
|
|
|
// HasError returns true if the response contains an error
|
|
func (r *Response) HasError() bool {
|
|
return r.Error != "" || r.ErrorDescription != ""
|
|
}
|
|
|
|
// UnmarshalJSON implements custom unmarshaling
|
|
func (r *Response) UnmarshalJSON(data []byte) error {
|
|
// First try to unmarshal as a standard response
|
|
type Alias Response
|
|
aux := &struct {
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(r),
|
|
}
|
|
if err := json.Unmarshal(data, aux); err != nil {
|
|
return err
|
|
}
|
|
|
|
// If result is missing, wrap the whole response in result
|
|
if r.Result == nil {
|
|
r.Result = data
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeJSON creates a Response from JSON data
|
|
func DeJSON(data []byte) (*Response, error) {
|
|
var resp Response
|
|
if err := json.Unmarshal(data, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// Error types
|
|
var (
|
|
ErrUnauthorized = errors.New("unauthorized")
|
|
ErrBadRequest = errors.New("bad request")
|
|
ErrNotFound = errors.New("not found")
|
|
ErrNetwork = errors.New("network error")
|
|
ErrTimeout = errors.New("timeout")
|
|
ErrSchemaMismatch = errors.New("schema mismatch")
|
|
)
|
|
|
|
// YandexMusicError is the base error type
|
|
type YandexMusicError struct {
|
|
Message string
|
|
Err error
|
|
}
|
|
|
|
func (e *YandexMusicError) Error() string {
|
|
if e.Err != nil {
|
|
return e.Message + ": " + e.Err.Error()
|
|
}
|
|
return e.Message
|
|
}
|
|
|
|
func (e *YandexMusicError) Unwrap() error {
|
|
return e.Err
|
|
}
|
|
|
|
// NewYandexMusicError creates a new YandexMusicError
|
|
func NewYandexMusicError(message string, err error) *YandexMusicError {
|
|
return &YandexMusicError{Message: message, Err: err}
|
|
}
|
|
|
|
// IsUnauthorizedError checks if error is unauthorized
|
|
func IsUnauthorizedError(err error) bool {
|
|
var yme *YandexMusicError
|
|
if errors.As(err, &yme) {
|
|
return errors.Is(yme.Err, ErrUnauthorized)
|
|
}
|
|
return errors.Is(err, ErrUnauthorized)
|
|
}
|
|
|
|
// IsBadRequestError checks if error is bad request
|
|
func IsBadRequestError(err error) bool {
|
|
var yme *YandexMusicError
|
|
if errors.As(err, &yme) {
|
|
return errors.Is(yme.Err, ErrBadRequest)
|
|
}
|
|
return errors.Is(err, ErrBadRequest)
|
|
}
|
|
|
|
// IsNotFoundError checks if error is not found
|
|
func IsNotFoundError(err error) bool {
|
|
var yme *YandexMusicError
|
|
if errors.As(err, &yme) {
|
|
return errors.Is(yme.Err, ErrNotFound)
|
|
}
|
|
return errors.Is(err, ErrNotFound)
|
|
}
|
|
|
|
// IsNetworkError checks if error is network error
|
|
func IsNetworkError(err error) bool {
|
|
var yme *YandexMusicError
|
|
if errors.As(err, &yme) {
|
|
return errors.Is(yme.Err, ErrNetwork)
|
|
}
|
|
return errors.Is(err, ErrNetwork)
|
|
}
|
|
|
|
// IsTimeoutError checks if error is timeout
|
|
func IsTimeoutError(err error) bool {
|
|
var yme *YandexMusicError
|
|
if errors.As(err, &yme) {
|
|
return errors.Is(yme.Err, ErrTimeout)
|
|
}
|
|
return errors.Is(err, ErrTimeout)
|
|
}
|