Skip to content

Commit 60dbc27

Browse files
Marcel JiraMic92
authored andcommitted
re-throw BrokenPipeError as mpd.ConnectionError
1 parent e1b9bc7 commit 60dbc27

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

doc/changes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Changes in v0.6.0 (unreleased)
1111
* Introduce MPDClientBase class which provides common MPD communication related
1212
helpers. Used as base for synchronous and asynchronous clients
1313
* port argument is optional when connecting via unix sockets
14+
* python-mpd will now raise mpd.ConnectionError instead of socket.error, when
15+
connection is lost
1416

1517

1618
Changes in v0.5.5

mpd/base.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,24 @@ def _execute(self, command, args, retval):
463463
return retval
464464

465465
def _write_line(self, line):
466-
self._wfile.write("{}\n".format(line))
467-
self._wfile.flush()
466+
try:
467+
self._wfile.write("{}\n".format(line))
468+
self._wfile.flush()
469+
except socket.error as e:
470+
error_message = "Connection to server was reset"
471+
logger.info(error_message)
472+
self._reset()
473+
if IS_PYTHON2:
474+
# Utilizing exec is not particularly elegant, however, it seems
475+
# to be the only way as Python3 handles exceptions quite
476+
# different to Python2. Without exec, the whole script is not
477+
# executable in Python3. Also "six" does it the same way:
478+
# https://bitbucket.org/gutworth/six/src/ (search "reraise")
479+
exec('raise ConnectionError, "' + error_message + '",'
480+
'sys.exc_info()[2]')
481+
else:
482+
e = ConnectionError(error_message)
483+
raise e.with_traceback(sys.exc_info()[2])
468484

469485
def _write_command(self, command, args=[]):
470486
parts = [command]

mpd/tests.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,16 +345,28 @@ def test_set_timeout_from_connect(self):
345345
self.assertEqual(len(w), 1)
346346
self.assertIn('Use MPDClient.timeout', str(w[0].message))
347347

348+
@unittest.skipIf(sys.version_info < (3, 3), "BrokenPipeError was introduced in python 3.3")
349+
def test_broken_pipe_error(self):
350+
self.MPDWillReturn('volume: 63\n', 'OK\n')
351+
self.client._wfile.write.side_effect = BrokenPipeError
352+
self.socket_mock.error = Exception
353+
354+
with self.assertRaises(mpd.ConnectionError):
355+
self.client.status()
356+
348357
def test_connection_lost(self):
349358
# Simulate a connection lost: the socket returns empty strings
350359
self.MPDWillReturn('')
360+
self.socket_mock.error = Exception
351361

352362
with self.assertRaises(mpd.ConnectionError):
353363
self.client.status()
364+
self.socket_mock.unpack.assert_called()
354365

355366
# consistent behaviour, solves bug #11 (github)
356367
with self.assertRaises(mpd.ConnectionError):
357368
self.client.status()
369+
self.socket_mock.unpack.assert_called()
358370

359371
self.assertIs(self.client._sock, None)
360372

0 commit comments

Comments
 (0)