From 86e90f14c6233467a5f73dbd530fb048591e7a99 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Wed, 25 May 2011 20:47:52 +0200 Subject: [PATCH 1/4] Add MpdSystemError exception --- mopidy/frontends/mpd/exceptions.py | 5 +++++ tests/frontends/mpd/exception_test.py | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mopidy/frontends/mpd/exceptions.py b/mopidy/frontends/mpd/exceptions.py index faf4ce2f..df90aed7 100644 --- a/mopidy/frontends/mpd/exceptions.py +++ b/mopidy/frontends/mpd/exceptions.py @@ -54,6 +54,11 @@ class MpdNoExistError(MpdAckError): super(MpdNoExistError, self).__init__(*args, **kwargs) self.error_code = MpdAckError.ACK_ERROR_NO_EXIST +class MpdSystemError(MpdAckError): + def __init__(self, *args, **kwargs): + super(MpdSystemError, self).__init__(*args, **kwargs) + self.error_code = MpdAckError.ACK_ERROR_SYSTEM + class MpdNotImplemented(MpdAckError): def __init__(self, *args, **kwargs): super(MpdNotImplemented, self).__init__(*args, **kwargs) diff --git a/tests/frontends/mpd/exception_test.py b/tests/frontends/mpd/exception_test.py index ef222d46..9b1b47a2 100644 --- a/tests/frontends/mpd/exception_test.py +++ b/tests/frontends/mpd/exception_test.py @@ -1,7 +1,7 @@ import unittest from mopidy.frontends.mpd.exceptions import (MpdAckError, MpdUnknownCommand, - MpdNotImplemented) + MpdSystemError, MpdNotImplemented) class MpdExceptionsTest(unittest.TestCase): def test_key_error_wrapped_in_mpd_ack_error(self): @@ -36,3 +36,10 @@ class MpdExceptionsTest(unittest.TestCase): except MpdAckError as e: self.assertEqual(e.get_mpd_ack(), u'ACK [5@0] {} unknown command "play"') + + def test_mpd_system_error(self): + try: + raise MpdSystemError('foo') + except MpdSystemError as e: + self.assertEqual(e.get_mpd_ack(), + u'ACK [52@0] {} foo') From 63918ac3f3864ec315b1b0be63d5eb54e8fb750c Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Wed, 25 May 2011 20:52:54 +0200 Subject: [PATCH 2/4] Log a warning if MPD tries to communicate with dead actors. --- mopidy/frontends/mpd/dispatcher.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mopidy/frontends/mpd/dispatcher.py b/mopidy/frontends/mpd/dispatcher.py index f5c30b23..a72789f1 100644 --- a/mopidy/frontends/mpd/dispatcher.py +++ b/mopidy/frontends/mpd/dispatcher.py @@ -1,10 +1,12 @@ +import logging import re +from pykka import ActorDeadError from pykka.registry import ActorRegistry from mopidy.backends.base import Backend from mopidy.frontends.mpd.exceptions import (MpdAckError, MpdArgError, - MpdUnknownCommand) + MpdUnknownCommand, MpdSystemError) from mopidy.frontends.mpd.protocol import mpd_commands, request_handlers # Do not remove the following import. The protocol modules must be imported to # get them registered as request handlers. @@ -16,6 +18,8 @@ from mopidy.frontends.mpd.protocol import (audio_output, command_list, from mopidy.mixers.base import BaseMixer from mopidy.utils import flatten +logger = logging.getLogger('mopidy.frontends.mpd.dispatcher') + class MpdDispatcher(object): """ The MPD session feeds the MPD dispatcher with requests. The dispatcher @@ -49,6 +53,10 @@ class MpdDispatcher(object): if command_list_index is not None: e.index = command_list_index return self.handle_response(e.get_mpd_ack(), add_ok=False) + except ActorDeadError as e: + logger.warning(u'Tried to communicate with dead actor.') + mpd_error = MpdSystemError(e.message) + return self.handle_response(mpd_error.get_mpd_ack(), add_ok=False) if request in (u'command_list_begin', u'command_list_ok_begin'): return None if command_list_index is not None: From 55bc7b19fb1d4a1f7c311cf608176767b24031d5 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Wed, 25 May 2011 23:05:54 +0200 Subject: [PATCH 3/4] Remove dead code in BaseThread --- mopidy/utils/process.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/mopidy/utils/process.py b/mopidy/utils/process.py index dbc6cada..cf676519 100644 --- a/mopidy/utils/process.py +++ b/mopidy/utils/process.py @@ -21,26 +21,17 @@ class BaseThread(threading.Thread): self.run_inside_try() except KeyboardInterrupt: logger.info(u'Interrupted by user') - self.exit(0, u'Interrupted by user') except SettingsError as e: logger.error(e.message) - self.exit(1, u'Settings error') except ImportError as e: logger.error(e) - self.exit(2, u'Import error') except Exception as e: logger.exception(e) - self.exit(3, u'Unknown error') + logger.debug(u'%s: Exiting thread', self.name) def run_inside_try(self): raise NotImplementedError - def destroy(self): - pass - - def exit(self, status=0, reason=None): - self.destroy() - class GObjectEventThread(BaseThread): """ From 3b27ba47464aad9d79b8378d19c30e23bfca809d Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Wed, 25 May 2011 23:06:15 +0200 Subject: [PATCH 4/4] Catch and log ActorDeadError in BaseThread --- mopidy/utils/process.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mopidy/utils/process.py b/mopidy/utils/process.py index cf676519..7f6cf664 100644 --- a/mopidy/utils/process.py +++ b/mopidy/utils/process.py @@ -4,6 +4,8 @@ import threading import gobject gobject.threads_init() +from pykka import ActorDeadError + from mopidy import SettingsError logger = logging.getLogger('mopidy.utils.process') @@ -25,6 +27,8 @@ class BaseThread(threading.Thread): logger.error(e.message) except ImportError as e: logger.error(e) + except ActorDeadError as e: + logger.warning(e) except Exception as e: logger.exception(e) logger.debug(u'%s: Exiting thread', self.name)