core: Update PlaylistsController to catch backend exceptions
This commit is contained in:
parent
66771dec68
commit
50f68064be
@ -3,8 +3,6 @@ from __future__ import absolute_import, unicode_literals
|
||||
import logging
|
||||
import urlparse
|
||||
|
||||
import pykka
|
||||
|
||||
from mopidy.core import listener
|
||||
from mopidy.models import Playlist
|
||||
from mopidy.utils import deprecation
|
||||
@ -32,17 +30,21 @@ class PlaylistsController(object):
|
||||
.. versionadded:: 1.0
|
||||
"""
|
||||
futures = {
|
||||
b.actor_ref.actor_class.__name__: b.playlists.as_list()
|
||||
for b in set(self.backends.with_playlists.values())}
|
||||
backend: backend.playlists.as_list()
|
||||
for backend in set(self.backends.with_playlists.values())}
|
||||
|
||||
results = []
|
||||
for backend_name, future in futures.items():
|
||||
for backend, future in futures.items():
|
||||
try:
|
||||
results.extend(future.get())
|
||||
except NotImplementedError:
|
||||
backend_name = backend.actor_ref.actor_class.__name__
|
||||
logger.warning(
|
||||
'%s does not implement playlists.as_list(). '
|
||||
'Please upgrade it.', backend_name)
|
||||
except Exception:
|
||||
logger.exception('%s backend caused an exception.',
|
||||
backend.actor_ref.actor_class.__name__)
|
||||
|
||||
return results
|
||||
|
||||
@ -191,6 +193,8 @@ class PlaylistsController(object):
|
||||
else:
|
||||
return None
|
||||
|
||||
# TODO: there is an inconsistency between library.refresh(uri) and this
|
||||
# call, not sure how to sort this out.
|
||||
def refresh(self, uri_scheme=None):
|
||||
"""
|
||||
Refresh the playlists in :attr:`playlists`.
|
||||
@ -204,15 +208,27 @@ class PlaylistsController(object):
|
||||
:type uri_scheme: string
|
||||
"""
|
||||
if uri_scheme is None:
|
||||
futures = [b.playlists.refresh()
|
||||
for b in self.backends.with_playlists.values()]
|
||||
pykka.get_all(futures)
|
||||
listener.CoreListener.send('playlists_loaded')
|
||||
futures = {b: b.playlists.refresh()
|
||||
for b in self.backends.with_playlists.values()}
|
||||
playlists_loaded = False
|
||||
for backend, future in futures.items():
|
||||
try:
|
||||
future.get()
|
||||
playlists_loaded = True
|
||||
except Exception:
|
||||
logger.exception('%s backend caused an exception.',
|
||||
backend.actor_ref.actor_class.__name__)
|
||||
if playlists_loaded:
|
||||
listener.CoreListener.send('playlists_loaded')
|
||||
else:
|
||||
backend = self.backends.with_playlists.get(uri_scheme, None)
|
||||
if backend:
|
||||
backend.playlists.refresh().get()
|
||||
listener.CoreListener.send('playlists_loaded')
|
||||
try:
|
||||
backend.playlists.refresh().get()
|
||||
listener.CoreListener.send('playlists_loaded')
|
||||
except Exception:
|
||||
logger.exception('%s backend caused an exception.',
|
||||
backend.actor_ref.actor_class.__name__)
|
||||
|
||||
def save(self, playlist):
|
||||
"""
|
||||
|
||||
@ -279,3 +279,42 @@ class DeprecatedGetPlaylistsTest(BasePlaylistsTest):
|
||||
self.assertEqual(len(result[0].tracks), 0)
|
||||
self.assertEqual(result[1].name, 'B')
|
||||
self.assertEqual(len(result[1].tracks), 0)
|
||||
|
||||
|
||||
@mock.patch('mopidy.core.playlists.logger')
|
||||
class BackendFailuresCorePlaylistsTest(unittest.TestCase):
|
||||
|
||||
def setUp(self): # noqa: N802
|
||||
self.playlists = mock.Mock(spec=backend.PlaylistsProvider)
|
||||
|
||||
self.backend = mock.Mock()
|
||||
self.backend.actor_ref.actor_class.__name__ = 'DummyBackend'
|
||||
self.backend.uri_schemes.get.return_value = ['dummy']
|
||||
self.backend.playlists = self.playlists
|
||||
|
||||
self.core = core.Core(mixer=None, backends=[self.backend])
|
||||
|
||||
def test_as_list_backend_exception_gets_ignored(self, logger):
|
||||
self.playlists.as_list.get.side_effect = Exception
|
||||
self.assertEqual([], self.core.playlists.as_list())
|
||||
logger.exception.assert_called_with(mock.ANY, 'DummyBackend')
|
||||
|
||||
def test_get_items_backend_exception_gets_through(self, logger):
|
||||
# TODO: is this behavior desired?
|
||||
self.playlists.get_items.return_value.get.side_effect = Exception
|
||||
with self.assertRaises(Exception):
|
||||
self.core.playlists.get_items('dummy:/1')
|
||||
|
||||
@mock.patch('mopidy.core.listener.CoreListener.send')
|
||||
def test_refresh_backend_exception_gets_ignored(self, send, logger):
|
||||
self.playlists.refresh.return_value.get.side_effect = Exception
|
||||
self.core.playlists.refresh()
|
||||
self.assertFalse(send.called)
|
||||
logger.exception.assert_called_with(mock.ANY, 'DummyBackend')
|
||||
|
||||
@mock.patch('mopidy.core.listener.CoreListener.send')
|
||||
def test_refresh_uri_backend_exception_gets_ignored(self, send, logger):
|
||||
self.playlists.refresh.return_value.get.side_effect = Exception
|
||||
self.core.playlists.refresh('dummy')
|
||||
self.assertFalse(send.called)
|
||||
logger.exception.assert_called_with(mock.ANY, 'DummyBackend')
|
||||
|
||||
Loading…
Reference in New Issue
Block a user