From 496b99d0b3681f3b65744b0f9ca7ba718015efa4 Mon Sep 17 00:00:00 2001 From: Jc2k Date: Thu, 4 Jul 2024 12:22:17 +0100 Subject: [PATCH] Don't load_provider if provider already deleted (#1436) --- music_assistant/server/controllers/config.py | 6 ++-- music_assistant/server/server.py | 33 ++++++++++++++++---- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/music_assistant/server/controllers/config.py b/music_assistant/server/controllers/config.py index e2d1e86f..e504ee30 100644 --- a/music_assistant/server/controllers/config.py +++ b/music_assistant/server/controllers/config.py @@ -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) diff --git a/music_assistant/server/server.py b/music_assistant/server/server.py index 4a0ec37d..65955443 100644 --- a/music_assistant/server/server.py +++ b/music_assistant/server/server.py @@ -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.""" -- 2.34.1