lyarenei / jellyfin-plugin-listenbrainz

ListenBrainz plugin for Jellyfin.
MIT License
79 stars 3 forks source link

[Bug]: Saving listen cache fails with an exception #87

Closed Maxr1998 closed 9 months ago

Maxr1998 commented 9 months ago

Bug description

During a short ListenBrainz downtime yesterday, listen submission failed, but after the retry limit was reached, an exception was thrown instead of persisting the listen to the cache.

Steps to reproduce

  1. Have ListenBrainz unreachable/time out
  2. Listen to any song
  3. Find stack trace in logs after a while

Expected behavior

The listen should've been submitted to the cache to submit later.

Actual behavior

There was an exception, see logs.

Jellyfin logs

Feb 23 05:05:04 iridium docker[13873]: [04:05:04] [DBG] [81] Jellyfin.Plugin.ListenBrainz: Sending request:
Feb 23 05:05:04 iridium docker[13873]: Method: POST
Feb 23 05:05:04 iridium docker[13873]: URI: https://api.listenbrainz.org/1/submit-listens
Feb 23 05:05:04 iridium docker[13873]: Data: {"listen_type":"single","payload":[{"listened_at":1708659912,"track_metadata":{"artist_name":"TRI.BE","track_name":"Diamond","release_name":"Diamond","additional_info":{"artist_mbids":["3ee9d430-5c76-4947-83bf-ebb5a9e3419c"],"release_group_mbid":"e4855b8b-513b-48c3-ae83-033cfc2b35e2","release_mbid":"af1f5b4a-a27b-4bcd-921a-5517efd97724","recording_mbid":"bdff7905-35b6-4134-84f4-0d36756082b9","track_mbid":"b0d817ab-b56d-4de3-9f92-86360d214e6c","tracknumber":1,"isrc":"KRUM72400013","tags":[],"media_player":"Jellyfin","submission_client":"ListenBrainz plugin for Jellyfin","submission_client_version":"3.4.0.0","duration_ms":183000}}}]}
Feb 23 05:06:04 iridium docker[13873]: [04:06:04] [DBG] [76] Jellyfin.Plugin.ListenBrainz: Request has been processed, freeing up resources
Feb 23 05:06:04 iridium docker[13873]: [04:06:04] [INF] [68] Jellyfin.Plugin.ListenBrainz: Failed to send listen: One or more errors occurred. (Retry limit reached)
Feb 23 05:06:04 iridium docker[13873]: [04:06:04] [DBG] [68] Jellyfin.Plugin.ListenBrainz: Failed to send listen
Feb 23 05:06:04 iridium docker[13873]: System.AggregateException: One or more errors occurred. (Retry limit reached)
Feb 23 05:06:04 iridium docker[13873]:  ---> Jellyfin.Plugin.ListenBrainz.Http.Exceptions.RetryException: Retry limit reached
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Http.HttpClient.SendRequest(HttpRequestMessage requestMessage, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Api.BaseApiClient.DoRequestWithRetry(HttpRequestMessage requestMessage, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Api.BaseApiClient.DoRequest[TResponse](HttpRequestMessage requestMessage, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Api.BaseApiClient.SendPostRequest[TRequest,TResponse](TRequest request, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Api.ListenBrainzApiClient.SubmitListens(SubmitListensRequest request, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    --- End of inner exception stack trace ---
Feb 23 05:06:04 iridium docker[13873]:    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
Feb 23 05:06:04 iridium docker[13873]:    at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
Feb 23 05:06:04 iridium docker[13873]:    at System.Threading.Tasks.Task.Wait()
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Clients.ListenBrainzClient.SendListen(UserConfig config, Audio item, AudioItemMetadata metadata, Int64 listenedAt)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.PluginImplementation.OnPlaybackStop(Object sender, PlaybackStopEventArgs args)
Feb 23 05:06:04 iridium docker[13873]: [04:06:04] [ERR] [68] Emby.Server.Implementations.Session.SessionManager: Error in event handler
Feb 23 05:06:04 iridium docker[13873]: Jellyfin.Plugin.ListenBrainz.Exceptions.PluginException: Saving cache failed
Feb 23 05:06:04 iridium docker[13873]:  ---> System.IO.FileNotFoundException: Could not load file or assembly 'Jellyfin.Plugin.ListenBrainz.MusicBrainzApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
Feb 23 05:06:04 iridium docker[13873]: File name: 'Jellyfin.Plugin.ListenBrainz.MusicBrainzApi, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null'
Feb 23 05:06:04 iridium docker[13873]:    at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
Feb 23 05:06:04 iridium docker[13873]:    at System.Reflection.RuntimeConstructorInfo.<get_Signature>g__LazyCreateSignature|19_0()
Feb 23 05:06:04 iridium docker[13873]:    at System.Reflection.RuntimeConstructorInfo.GetParameters()
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Reflection.ReflectionExtensions.TryGetDeserializationConstructor(Type type, Boolean useDefaultCtorInAnnotatedStructs, ConstructorInfo& deserializationCtor)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Converters.ObjectConverterFactory.CreateConverter(Type typeToConvert, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonConverterFactory.GetConverterInternal(Type typeToConvert, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializerOptions.GetConverterInternal(Type typeToConvert)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializerOptions.DetermineConverter(Type parentClassType, Type runtimePropertyType, MemberInfo memberInfo)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Metadata.JsonTypeInfo.GetConverter(Type type, Type parentClassType, MemberInfo memberInfo, Type& runtimeType, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Metadata.JsonTypeInfo.AddProperty(MemberInfo memberInfo, Type memberType, Type parentClassType, Boolean isVirtual, Nullable`1 parentTypeNumberHandling, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Metadata.JsonTypeInfo..ctor(Type type, JsonConverter converter, Type runtimeType, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializerOptions.<InitializeForReflectionSerializer>g__CreateJsonTypeInfo|112_0(Type type, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializerOptions.GetOrAddClass(Type type)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Metadata.JsonTypeInfo.get_ElementTypeInfo()
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryWrite(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.Converters.DictionaryOfTKeyTValueConverter`3.OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonDictionaryConverter`3.OnTryWrite(Utf8JsonWriter writer, TDictionary dictionary, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonConverter`1.TryWrite(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.Serialization.JsonConverter`1.WriteCore(Utf8JsonWriter writer, T& value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializer.WriteCore[TValue](JsonConverter jsonConverter, Utf8JsonWriter writer, TValue& value, JsonSerializerOptions options, WriteStack& state)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializer.WriteStream[TValue](Stream utf8Json, TValue& value, JsonTypeInfo jsonTypeInfo)
Feb 23 05:06:04 iridium docker[13873]:    at System.Text.Json.JsonSerializer.Serialize[TValue](Stream utf8Json, TValue value, JsonSerializerOptions options)
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Managers.ListensCacheManager.Save()
Feb 23 05:06:04 iridium docker[13873]:    --- End of inner exception stack trace ---
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.Managers.ListensCacheManager.Save()
Feb 23 05:06:04 iridium docker[13873]:    at Jellyfin.Plugin.ListenBrainz.PluginImplementation.OnPlaybackStop(Object sender, PlaybackStopEventArgs args)
Feb 23 05:06:04 iridium docker[13873]:    at MediaBrowser.Common.Events.EventHelper.<>c__DisplayClass1_0`1.<QueueEventIfNotNull>b__0()

Plugin version

3.4.0.0

Jellyfin Version

10.8.13

Additional info

This may or may not be related to #85. For what it's worth, I don't have the Cover Art Archive plugin installed. Apart from ListenBrainz, I only use preinstalled plugins.

Comparison of plugin directories for 3.3.2.0 and 3.4.0.0:

ListenBrainz_3.3.2.0:
total 156K
-rw-r--r-- 1 max max   48 Feb  7 18:29 cache.json
-rw-r--r-- 1 max max  60K Feb 22 16:50 image.svg
-rw-r--r-- 1 max max  31K Jan 30 10:37 Jellyfin.Plugin.ListenBrainz.Api.dll
-rw-r--r-- 1 max max 113K Jan 30 10:37 Jellyfin.Plugin.ListenBrainz.dll
-rw-r--r-- 1 max max  15K Jan 30 10:37 Jellyfin.Plugin.ListenBrainz.Http.dll
-rw-r--r-- 1 max max  16K Jan 30 10:37 Jellyfin.Plugin.ListenBrainz.MusicBrainzApi.dll
-rw-r--r-- 1 max max  646 Feb 22 16:50 meta.json

ListenBrainz_3.4.0.0:
total 365K
-rw-r--r-- 1 max max    0 Feb 23 05:06 cache.json
-rw-r--r-- 1 max max  60K Feb 19 16:50 image.svg
-rw-r--r-- 1 max max  35K Feb 17 11:56 Jellyfin.Plugin.ListenBrainz.Api.dll
-rw-r--r-- 1 max max 126K Feb 17 11:56 Jellyfin.Plugin.ListenBrainz.dll
-rw-r--r-- 1 max max  16K Feb 17 11:56 Jellyfin.Plugin.ListenBrainz.Http.dll
-rw-r--r-- 1 max max  20K Feb 17 11:56 MetaBrainz.Common.dll
-rw-r--r-- 1 max max  28K Feb 17 11:56 MetaBrainz.Common.Json.dll
-rw-r--r-- 1 max max 293K Feb 17 11:56 MetaBrainz.MusicBrainz.dll
-rw-r--r-- 1 max max  865 Feb 23 04:15 meta.json
lyarenei commented 9 months ago

Hi @Maxr1998 thanks for reporting and sorry for the inconvenience.

Since this is caused by missing MusicBrainz DLL, this will be fixed in the next release, where the move to the 3rd party MusicBrainz client is reverted. The move to the 3rd party MusicBrainz library was not handled very well and I have really no excuses for that.

I expect the next release will be released later today.

Maxr1998 commented 9 months ago

No worries, it wasn't a huge issue. I could easily recover the failed listen from the logs. Glad to hear it will be fixed soon. Hopefully, the migration will work out for a later release.

lyarenei commented 9 months ago

No worries, it wasn't a huge issue. I could easily recover the failed listen from the logs.

I see, goo to hear. 🙂

Version 3.4.1.0 should work again.