Handle invalid items in streaming provider
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 20 Jul 2023 13:16:13 +0000 (15:16 +0200)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 20 Jul 2023 13:16:13 +0000 (15:16 +0200)
music_assistant/server/controllers/media/base.py
music_assistant/server/models/music_provider.py

index d81b80f3ca4fecda0eff53927d8639977258dada..d05f1532f78ef4eed70236d5683cb64880a91fbc 100644 (file)
@@ -412,23 +412,10 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         fallback = fallback or await self.get_library_item_by_prov_id(
             item_id, provider_instance_id_or_domain
         )
-        if fallback and isinstance(fallback, ItemMapping):
-            # create a fake item on the fly from the ItemMapping details
-            fallback_item: MediaItemType = self.item_cls(
-                item_id=fallback.item_id, provider=fallback.provider, name=fallback.name
-            )
-            if provider := self.mass.get_provider(fallback_item.provider):
-                fallback_item.provider_mappings.add(
-                    ProviderMapping(
-                        item_id=fallback_item.item_id,
-                        provider_domain=provider.domain,
-                        provider_instance=provider.instance_id,
-                        available=False,
-                    )
-                )
-                return fallback_item
-        elif fallback:
+        if fallback and not (isinstance(fallback, ItemMapping) and self.item_cls in (Track, Album)):
             # simply return the fallback item (marked as unavailable)
+            # NOTE: we only accept ItemMapping as fallback for flat items
+            # so not for tracks and albums (which rely on other objects)
             fallback.available = False
             return fallback
         # all options exhausted, we really can not find this item
index d9c2b16d504b2fb1fdab8eb08266ce6ab9f41307..d256b659527dfd5f9eb7c9a6a062bb58cc71d6f8 100644 (file)
@@ -4,7 +4,7 @@ from __future__ import annotations
 from collections.abc import AsyncGenerator
 
 from music_assistant.common.models.enums import MediaType, ProviderFeature
-from music_assistant.common.models.errors import MediaNotFoundError
+from music_assistant.common.models.errors import MediaNotFoundError, MusicAssistantError
 from music_assistant.common.models.media_items import (
     Album,
     AlbumTrack,
@@ -409,22 +409,25 @@ class MusicProvider(Provider):
                 library_item = await controller.get_library_item_by_prov_mappings(
                     prov_item.provider_mappings,
                 )
-                if not library_item:
-                    # create full db item
-                    # note that we skip the metadata lookup purely to speed up the sync
-                    # the additional metadata is then lazy retrieved afterwards
-                    prov_item.favorite = True
-                    library_item = await controller.add_item_to_library(
-                        prov_item, skip_metadata_lookup=True
-                    )
-                elif (
-                    library_item.metadata.checksum and prov_item.metadata.checksum
-                ) and library_item.metadata.checksum != prov_item.metadata.checksum:
-                    # existing dbitem checksum changed
-                    library_item = await controller.update_item_in_library(
-                        library_item.item_id, prov_item
-                    )
-                cur_db_ids.add(library_item.item_id)
+                try:
+                    if not library_item:
+                        # create full db item
+                        # note that we skip the metadata lookup purely to speed up the sync
+                        # the additional metadata is then lazy retrieved afterwards
+                        prov_item.favorite = True
+                        library_item = await controller.add_item_to_library(
+                            prov_item, skip_metadata_lookup=True
+                        )
+                    elif (
+                        library_item.metadata.checksum and prov_item.metadata.checksum
+                    ) and library_item.metadata.checksum != prov_item.metadata.checksum:
+                        # existing dbitem checksum changed
+                        library_item = await controller.update_item_in_library(
+                            library_item.item_id, prov_item
+                        )
+                    cur_db_ids.add(library_item.item_id)
+                except MusicAssistantError as err:
+                    self.logger.warning("Skipping sync of item %s: %s", prov_item.uri, str(err))
 
             # process deletions (= no longer in library)
             cache_key = f"library_items.{media_type}.{self.instance_id}"