Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ python:
- "3.4"
- "3.5"
- "3.6"
- "3.6-dev"
- "3.7-dev"
- "nightly"
- "pypy"
Expand Down
2 changes: 2 additions & 0 deletions doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Changes in v0.6.0 (unreleased)
* Introduce MPDClientBase class which provides common MPD communication related
helpers. Used as base for synchronous and asynchronous clients
* port argument is optional when connecting via unix sockets
* python-mpd will now raise mpd.ConnectionError instead of socket.error, when
connection is lost


Changes in v0.5.5
Expand Down
20 changes: 18 additions & 2 deletions mpd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,24 @@ def _execute(self, command, args, retval):
return retval

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

def _write_command(self, command, args=[]):
parts = [command]
Expand Down
12 changes: 12 additions & 0 deletions mpd/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,28 @@ def test_set_timeout_from_connect(self):
self.assertEqual(len(w), 1)
self.assertIn('Use MPDClient.timeout', str(w[0].message))

@unittest.skipIf(sys.version_info < (3, 3), "BrokenPipeError was introduced in python 3.3")
def test_broken_pipe_error(self):
self.MPDWillReturn('volume: 63\n', 'OK\n')
self.client._wfile.write.side_effect = BrokenPipeError
self.socket_mock.error = Exception

with self.assertRaises(mpd.ConnectionError):
self.client.status()

def test_connection_lost(self):
# Simulate a connection lost: the socket returns empty strings
self.MPDWillReturn('')
self.socket_mock.error = Exception

with self.assertRaises(mpd.ConnectionError):
self.client.status()
self.socket_mock.unpack.assert_called()

# consistent behaviour, solves bug #11 (github)
with self.assertRaises(mpd.ConnectionError):
self.client.status()
self.socket_mock.unpack.assert_called()

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

Expand Down