zmb3 / spotify

A Go wrapper for the Spotify Web API
Apache License 2.0
1.33k stars 283 forks source link

unmarshal fail. 【curl --request GET \ --url https://api.spotify.com/v1/artists/0TnOYISbd1XYRBk9myaseg】 #243

Closed kristopher8 closed 3 months ago

kristopher8 commented 5 months ago

json: cannot unmarshal number 1.1113535E7 into Go struct field Followers.followers.total of type uint

leonid-ed commented 5 months ago

Hi @kristopher8 , looks like this is an issue on Spotify side.

I've created a ticket there – would be great if you also add your comment there to make it more visible for the Spotify team.

tmstn commented 5 months ago

I've created a temporary workaround for this issue by adding custom Unmarshal methods to the structs that have inconsistencies.

// FullArtist (artists.go) 
func (f *FullArtist) UnmarshalJSON(data []byte) error {
    var v struct {
        SimpleArtist
        Popularity float64   `json:"popularity"`
        Genres     []string  `json:"genres"`
        Followers  Followers `json:"followers"`
        Images     []Image   `json:"images"`
    }

    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }

    f.SimpleArtist = v.SimpleArtist
    f.Popularity = int(v.Popularity)
    f.Genres = v.Genres
    f.Followers = v.Followers
    f.Images = v.Images

    return nil
}
// Followers (spotify.go)
func (f *Followers) UnmarshalJSON(data []byte) error {
    var v struct {
        Count    float64 `json:"total"`
        Endpoint string  `json:"href"`
    }

    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }

    f.Count = uint(v.Count)
    f.Endpoint = v.Endpoint

    return nil
}
// Image (spotify.go)
func (i *Image) UnmarshalJSON(data []byte) error {
    var v struct {
        Height float64 `json:"height"`
        Width  float64 `json:"width"`
        URL    string  `json:"url"`
    }

    if err := json.Unmarshal(data, &v); err != nil {
        return err
    }

    i.Height = int(v.Height)
    i.Width = int(v.Width)
    i.URL = v.URL

    return nil
}

This should be compatible with endpoints that return integer values as all json numbers are floats by default

leonid-ed commented 4 months ago

@tmstn I've applied your fix in my fork and it worked! Thanks a lot!

wernerdweight commented 4 months ago

I created a PR with the changes from @tmstn.

wernerdweight commented 4 months ago

The float numbers are now actually also in other fields on track structs (SimpleTrack, FullTrack, at least). A custom numeric type would probably be a better solution than custom unmarshaling in this PR. 🤔

strideynet commented 4 months ago

Thanks folks - apologies for not commenting on this. I've been keeping an eye on it and was hoping Spotify would address this, but in typical Spotify fashion, it looks like we won't be seeing a fix on their side.