]> kaliko git repositories - mpd-sima.git/commitdiff
Cleanup PlayerError exception wrapper dev
authorkaliko <kaliko@azylum.org>
Sat, 10 Feb 2024 16:48:34 +0000 (17:48 +0100)
committerkaliko <kaliko@azylum.org>
Sat, 10 Feb 2024 16:48:34 +0000 (17:48 +0100)
sima/mpdclient.py
sima/utils/utils.py

index b50df91fca637f961f3335637ee06274094aa25a..99f69474258a513cbe6567dce875b11f012c4446 100644 (file)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2009-2021 kaliko <kaliko@azylum.org>
+# Copyright (c) 2009-2022, 2024 kaliko <kaliko@azylum.org>
 #
 #  This file is part of sima
 #
@@ -31,6 +31,7 @@ from .lib.meta import Meta, Artist, Album
 from .lib.track import Track
 from .lib.simastr import SimaStr
 from .utils.leven import levenshtein_ratio
+from .utils.utils import get_decorator
 
 
 # Some decorators
@@ -76,6 +77,9 @@ def tracks_wrapper(func):
             return Track(**ret)
         return [Track(**t) for t in ret]
     return wrapper
+
+# Decorator to wrap non MPDError exceptions from musicpd in PlayerError
+we = get_decorator(errors=(OSError, TimeoutError), wrap_into=PlayerError)
 # / decorators
 
 
@@ -116,15 +120,13 @@ class MPD(MPDClient):
         self._cache = None
 
     # ######### Overriding MPDClient ###########
+    @we
     def __getattr__(self, cmd):
         """Wrapper around MPDClient calls for abstract overriding"""
         track_wrapped = {'currentsong', 'find', 'playlistinfo', }
-        try:
-            if cmd in track_wrapped:
-                return tracks_wrapper(super().__getattr__(cmd))
-            return super().__getattr__(cmd)
-        except OSError as err:  # socket errors
-            raise PlayerError(err) from err
+        if cmd in track_wrapped:
+            return tracks_wrapper(super().__getattr__(cmd))
+        return super().__getattr__(cmd)
 
     def disconnect(self):
         """Overriding explicitly MPDClient.disconnect()"""
@@ -139,23 +141,9 @@ class MPD(MPDClient):
         port = mpd_config.get('port')
         password = mpd_config.get('password', fallback=None)
         self.disconnect()
-        try:
-            super().connect(host, port)
-        # Catch socket errors
-        except OSError as err:
-            raise PlayerError(f'Could not connect to "{host}:{port}": {err.strerror}'
-                             ) from err
-        # Catch all other possible errors
-        # ConnectionError and ProtocolError are always fatal.  Others may not
-        # be, but we don't know how to handle them here, so treat them as if
-        # they are instead of ignoring them.
-        except PlayerError as err:
-            raise PlayerError(f'Could not connect to "{host}:{port}": {err}') from err
+        super().connect(host, port)
         if password:
-            try:
-                self.password(password)
-            except OSError as err:
-                raise PlayerError(f"Could not connect to '{host}': {err}") from err
+            self.password(password)
         # Controls we have sufficient rights
         available_cmd = self.commands()
         for cmd in MPD.needed_cmds:
@@ -219,6 +207,7 @@ class MPD(MPDClient):
             return False
         return self.current.id != previous.id  # pylint: disable=no-member
 
+    @we
     def monitor(self):
         """Monitor player for change
         Returns a list a events among:
@@ -231,21 +220,18 @@ class MPD(MPDClient):
         """
         curr = self.current
         select_timeout = 5
-        try:  # noidle cmd does not go through __getattr__, need to catch OSError then
-            while True:
-                self.send_idle('database', 'playlist', 'player', 'options')
-                _read, _, _ = select([self], [], [], select_timeout)
-                if _read:  # tries to read response
-                    ret = self.fetch_idle()
-                    if self._skipped_track(curr):
-                        ret.append('skipped')
-                    if 'database' in ret:
-                        self._reset_cache()
-                    return ret
-                #  Nothing to read, canceling idle
-                self.noidle()
-        except OSError as err:
-            raise PlayerError(err) from err
+        while True:
+            self.send_idle('database', 'playlist', 'player', 'options')
+            _read, _, _ = select([self], [], [], select_timeout)
+            if _read:  # tries to read response
+                ret = self.fetch_idle()
+                if self._skipped_track(curr):
+                    ret.append('skipped')
+                if 'database' in ret:
+                    self._reset_cache()
+                return ret
+            #  Nothing to read, canceling idle
+            self.noidle()
 
     def clean(self):
         """Clean blocking event (idle) and pending commands
@@ -255,6 +241,7 @@ class MPD(MPDClient):
         elif self._pending:
             self.log.warning('pending commands: %s', self._pending)
 
+    @we
     def add(self, payload):
         """Overriding MPD's add method to accept Track objects
 
index c148892d5276d7a4e684b795a28ac50b1bbbe971..cb672639e2e780d06187f641b9b0ac0c5d84ebe7 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (c) 2010, 2011, 2013, 2014, 2015, 2020, 2021 kaliko <kaliko@azylum.org>
+# Copyright (c) 2010, 2011, 2013, 2014, 2015, 2020, 2021, 2024 kaliko <kaliko@azylum.org>
 #
 #  This file is part of sima
 #
@@ -214,5 +214,21 @@ class WSHTTPError(WSError):
 class PluginException(MPDSimaException):
     pass
 
+
+# Wrap Exception decorator
+def get_decorator(errors=(OSError, TimeoutError), wrap_into=Exception):
+    def decorator(func):
+        def w_func(*args, **kwargs):
+            try:
+                return func(*args, **kwargs)
+            except errors as err:
+                strerr = str(err)
+                if hasattr(err, 'strerror'):
+                    if err.strerror:
+                        strerr = err.strerror
+                raise wrap_into(strerr) from err
+        return w_func
+    return decorator
+
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab