Don't load_provider if provider already deleted (#1436)
authorJc2k <john.carr@unrouted.co.uk>
Thu, 4 Jul 2024 11:22:17 +0000 (12:22 +0100)
committerGitHub <noreply@github.com>
Thu, 4 Jul 2024 11:22:17 +0000 (13:22 +0200)
music_assistant/server/controllers/config.py
music_assistant/server/server.py

index e2d1e86f92000e301507a88888d14b813aeae294..e504ee303c385d7f5669fb0f8a51ee8dcd912a2f 100644 (file)
@@ -818,7 +818,7 @@ class ConfigController:
         # validate the new config
         config.validate()
         # try to load the provider first to catch errors before we save it.
-        await self.mass.load_provider(config, raise_on_error=True)
+        await self.mass.load_provider_config(config)
         # the load was a success, store this config
         conf_key = f"{CONF_PROVIDERS}/{config.instance_id}"
         self.set(conf_key, config.to_raw())
@@ -833,8 +833,8 @@ class ConfigController:
                 deps.add(dep_prov.instance_id)
                 await self.mass.unload_provider(dep_prov.instance_id)
         # (re)load the provider
-        await self.mass.load_provider(config)
+        await self.mass.load_provider(config.instance_id)
         # reload any dependants
         for dep in deps:
             conf = await self.get_provider_config(dep)
-            await self.mass.load_provider(conf)
+            await self.mass.load_provider(conf.instance_id)
index 4a0ec37d4c61cbff074a166d38165b84e44705e5..659554432da576dbd7ebdf0f1f5c1885cdf1b351 100644 (file)
@@ -415,11 +415,9 @@ class MusicAssistant:
             raise RuntimeError(msg)
         self.command_handlers[command] = APICommandHandler.parse(command, handler)
 
-    async def load_provider(
+    async def load_provider_config(
         self,
         prov_conf: ProviderConfig,
-        raise_on_error: bool = False,
-        schedule_retry: int | None = 10,
     ) -> None:
         """Try to load a provider and catch errors."""
         try:
@@ -438,18 +436,41 @@ class MusicAssistant:
                     "Error loading provider(instance) %s",
                     prov_conf.name or prov_conf.domain,
                 )
+            raise
+
+    async def load_provider(
+        self,
+        instance_id: str,
+        raise_on_error: bool = False,
+        schedule_retry: int | None = 10,
+    ) -> None:
+        """Try to load a provider and catch errors."""
+        try:
+            prov_conf = await self.config.get_provider_config(instance_id)
+        except KeyError:
+            # Was deleted before we could run
+            return
+
+        if not prov_conf.enabled:
+            # Was disabled before we could run
+            return
+
+        try:
+            await self.load_provider_config(prov_conf)
+        # pylint: disable=broad-except
+        except Exception as exc:
             if raise_on_error:
                 raise
             # if loading failed, we store the error in the config object
             # so we can show something useful to the user
             prov_conf.last_error = str(exc)
-            self.config.set(f"{CONF_PROVIDERS}/{prov_conf.instance_id}/last_error", str(exc))
+            self.config.set(f"{CONF_PROVIDERS}/{instance_id}/last_error", str(exc))
             # auto schedule a retry if the (re)load failed
             if schedule_retry:
                 self.call_later(
                     schedule_retry,
                     self.load_provider,
-                    prov_conf,
+                    instance_id,
                     raise_on_error,
                     min(schedule_retry + 10, 600),
                 )
@@ -515,7 +536,7 @@ class MusicAssistant:
             for prov_conf in prov_configs:
                 if not prov_conf.enabled:
                     continue
-                tg.create_task(self.load_provider(prov_conf))
+                tg.create_task(self.load_provider(prov_conf.instance_id))
 
     async def _load_provider(self, conf: ProviderConfig) -> None:
         """Load (or reload) a provider."""