If you change your SoundCloud password, the auth token is invalidated and must be updated in mopidy.conf
. Until you do so, Mopidy-Soundcloud crashes hard with a stack trace:
$ mopidy
INFO Starting Mopidy 0.18.3-307-gcb6e19c
INFO Loading config from: builtin defaults, /etc/xdg/xdg-ubuntu/mopidy/mopidy.conf, /usr/share/upstart/xdg/mopidy/mopidy.conf, /etc/xdg/mopidy/mopidy.conf, /home/jodal/.config/mopidy/mopidy.conf, command line options
INFO Enabled extensions: spotify, mpd, http, stream, lux, scrobbler, mpris, moped, dirble, local, api_explorer, soundcloud
INFO Disabled extensions: beets, nad, gmusic, subsonic, radio-de, arcam
INFO Starting Mopidy audio
INFO Starting Mopidy backends: LocalBackend, StreamBackend, SoundCloudBackend, SpotifyBackend, DirbleBackend
INFO Loaded 0 local playlists from /home/jodal/.local/share/mopidy/local/playlists
INFO Loaded 0 local tracks using json
INFO Audio output set to "autoaudiosink"
INFO Audio mixer is using software mixing
INFO Mopidy uses SPOTIFY(R) CORE
INFO Starting Mopidy core
INFO Starting Mopidy frontends: MprisFrontend, ScrobblerFrontend, HttpFrontend, MpdFrontend
INFO MPRIS server connected to D-Bus
INFO MPD server running at [::]:6600
INFO HTTP server running at http://:::6680
INFO Connected to Spotify
INFO Scrobbler connected to Last.fm
INFO New MPD connection from [::ffff:127.0.0.1]:55797
INFO Searching SoundCloud for 'glycerine'
ERROR Unhandled exception in MpdSession (urn:uuid:6e6ea63f-0af0-4398-abbb-e2971b95e115):
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 200, in _actor_loop
response = self._handle_receive(message)
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 303, in _handle_receive
return self.on_receive(message)
File "/home/jodal/dev/mopidy/mopidy/utils/network.py", line 366, in on_receive
self.on_line_received(line)
File "/home/jodal/dev/mopidy/mopidy/mpd/session.py", line 33, in on_line_received
response = self.dispatcher.handle_request(line)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 46, in handle_request
return self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 75, in _catch_mpd_ack_errors_filter
return self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 85, in _authenticate_filter
return self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 104, in _command_list_filter
response = self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 133, in _idle_filter
response = self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 146, in _add_ok_filter
response = self._call_next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 67, in _call_next_filter
return next_filter(request, response, filter_chain)
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 158, in _call_handler_filter
response = self._format_response(self._call_handler(request))
File "/home/jodal/dev/mopidy/mopidy/mpd/dispatcher.py", line 167, in _call_handler
return protocol.commands.call(tokens, context=self.context)
File "/home/jodal/dev/mopidy/mopidy/mpd/protocol/__init__.py", line 171, in call
return self.handlers[tokens[0]](context, *tokens[1:])
File "/home/jodal/dev/mopidy/mopidy/mpd/protocol/__init__.py", line 140, in validate
return func(*args, **kwargs)
File "/home/jodal/dev/mopidy/mopidy/mpd/protocol/music_db.py", line 473, in search
results = context.core.library.search(**query).get()
File "/usr/lib/python2.7/dist-packages/pykka/future.py", line 299, in get
exec('raise exc_info[0], exc_info[1], exc_info[2]')
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 200, in _actor_loop
response = self._handle_receive(message)
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 294, in _handle_receive
return callee(*message['args'], **message['kwargs'])
File "/home/jodal/dev/mopidy/mopidy/core/library.py", line 193, in search
return [result for result in pykka.get_all(futures) if result]
File "/usr/lib/python2.7/dist-packages/pykka/future.py", line 330, in get_all
return [future.get(timeout=timeout) for future in futures]
File "/usr/lib/python2.7/dist-packages/pykka/future.py", line 299, in get
exec('raise exc_info[0], exc_info[1], exc_info[2]')
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 200, in _actor_loop
response = self._handle_receive(message)
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 294, in _handle_receive
return callee(*message['args'], **message['kwargs'])
File "/home/jodal/dev/mopidy-soundcloud/mopidy_soundcloud/library.py", line 177, in search
tracks=self.backend.remote.search(search_query)
File "/home/jodal/dev/mopidy-soundcloud/mopidy_soundcloud/soundcloud.py", line 212, in search
quote_plus(query)
File "/home/jodal/dev/mopidy-soundcloud/mopidy_soundcloud/soundcloud.py", line 238, in _get
res.raise_for_status()
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 773, in raise_for_status
raise HTTPError(http_error_msg, response=self)
HTTPError: 401 Client Error: Unauthorized
INFO Loaded 57 Spotify playlists
Traceback (most recent call last):
File "/home/jodal/dev/mopidy/mopidy/utils/network.py", line 271, in recv_callback
self.actor_ref.tell({'close': True})
File "/usr/lib/python2.7/dist-packages/pykka/actor.py", line 437, in tell
raise _ActorDeadError('%s not found' % self)
pykka.exceptions.ActorDeadError: MpdSession (urn:uuid:6e6ea63f-0af0-4398-abbb-e2971b95e115) not found
INFO New MPD connection from [::ffff:127.0.0.1]:55809
Mopidy-Soundcloud should catch 401 Unauthorized HTTP errors and log a good error message explaining possible reasons for the error instead of failing with an uncatched exception.