Viperinius / jellyfin-plugin-spotify-import

Import playlists from Spotify in Jellyfin
GNU General Public License v3.0
28 stars 2 forks source link

Json Error during Sync #18

Closed AlexLArmstrong closed 7 months ago

AlexLArmstrong commented 9 months ago

I get the following error on a freshly installed jellyfin instance when manually triggering a sync job:

[ERR] [47] Emby.Server.Implementations.ScheduledTasks.TaskManager: Error
Newtonsoft.Json.JsonReaderException: Error reading integer. Unexpected token: StartObject. Path 'duration_ms', line 1, position 285041.
   at Newtonsoft.Json.JsonReader.ReadAsInt32()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Populate(JsonReader reader, Object target)
   at SpotifyAPI.Web.PlayableItemConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
[... more Newtonsoft stack frames]
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at SpotifyAPI.Web.Http.NewtonsoftJSONSerializer.DeserializeResponse[T](IResponse response)
   at SpotifyAPI.Web.Http.APIConnector.DoSerializedRequest[T](IRequest request, CancellationToken cancel)
   at SpotifyAPI.Web.Http.APIConnector.SendAPIRequest[T](Uri uri, HttpMethod method, IDictionary`2 parameters, Object body, IDictionary`2 headers, CancellationToken cancel)
   at Viperinius.Plugin.SpotifyImport.Spotify.SpotifyPlaylistProvider.GetPlaylist(String playlistId, Nullable`1 cancellationToken)
   at Viperinius.Plugin.SpotifyImport.GenericPlaylistProvider.PopulatePlaylists(List`1 playlistIds, Nullable`1 cancellationToken)
   at Viperinius.Plugin.SpotifyImport.Tasks.SpotifyImportTask.ExecuteAsync(IProgress`1 progress, CancellationToken cancellationToken)
   at Emby.Server.Implementations.ScheduledTasks.ScheduledTaskWorker.ExecuteInternal(TaskOptions options)
[INF] [47] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Import Spotify playlists" Failed after 0 minute(s) and 39 seconds

For reasons unknown an exception in SpotifyAPI playableItemConverter is thrown.

Usually, exceptions in the library are caught in SpotifyPlaylistProvider, but this one is not since it is a JsonReaderException.

As a result the sync tasks stops with errors.

Expected Behavior

The exception should not be thrown in the first place, but if it still happens I would expect this to be logged as a warning and the sync process should continue.

Solutions

A quick fix for now could be to add a catch (JsonException) block. This would however not solve the underlying issue, which might come from the used SpotifyWeb library. (@JohnnyCrazy ?)

JohnnyCrazy commented 9 months ago

Hi,

The error seems to indicate that duration_ms is an object rather than a number. I never saw this happening before. But with the Spotify web api, you never know. They like to break things. Do you have the playlist ID used in this api call?

AlexLArmstrong commented 9 months ago

Sadly no, the exception does not log the playlist ID.

Viperinius commented 9 months ago

@AlexLArmstrong I added a temporary catch that logs the ID. Could you try with this branch again? https://github.com/Viperinius/jellyfin-plugin-spotify-import/tree/fix/json-except

AlexLArmstrong commented 8 months ago

I found the id, removed the playlist from the Spotify account and it works again...
Do you have a script to call the api with the ID for me to see what the difference in the response is?
With that I could add some more details to this issue

JohnnyCrazy commented 8 months ago

Would you be comfortable with sharing the ID? Everyone can access the playlist knowing the ID.

If not, you can also use this page: https://developer.spotify.com/documentation/web-api/reference/get-playlists-tracks

AlexLArmstrong commented 8 months ago

Okay, for some reason exactly one "duration_ms" is an object: "duration_ms": { "totalMilliseconds": 12345 }, but only on the https://api.spotify.com/v1/playlists/{playlist_id} and not the https://api.spotify.com/v1/playlists/{playlist_id}/tracks

its also interesting that there seems to be no album and no artist for this particular track...

    album: {
        album_type: null,
        available_markets: [],
        external_urls: {},
        href: null,
        id: null,
        images: [],
        name: "",
        release_date: null,
        release_date_precision: null,
        type: "album",
        uri: null,
        artists: []
    },
    artists: [
        {
            external_urls: {},
            href: null,
            id: null,
            name: "",
            type: "artist",
            uri: null
        }
    ]

The song seems to have been deleted from the Spotify catalog as I cannot manually select and play the song through the regular web UI.

JohnnyCrazy commented 8 months ago

Do you have the track ID?

AlexLArmstrong commented 8 months ago

no, the track does not have an ID

AlexLArmstrong commented 8 months ago

It is the only track with the is_local flag set to true, which according to documentation indicates that the file is a local file

JohnnyCrazy commented 8 months ago

Weird, even if it's a local track, the API should not deliver that kind of response.

I guess you could report it on the spotify developer forums but don't expect a response. Doesn't seem like something we need to fix here or in SpotifyAPI-NET.

AlexLArmstrong commented 8 months ago

understandable, wrapping the json error in a SpotifyAPI-NET exception and adding some hint on what might be going on could help other projects catch it with their normal exception handling and also troubleshoot the issue faster... some exception message like "a json deserialization error occurred. The Spotify API is known to be inconsistent. {api call info here}"

for us @Viperinius, I'd say we keep the catch from your fix and add additional debug information about which playlist etc was involved, maybe even reference this issue. what do you think?

Viperinius commented 8 months ago

Yeah, I'll add the catch to other api calls as well, just in case, and add some logging