python-mpd2 icon indicating copy to clipboard operation
python-mpd2 copied to clipboard

Connection lost when using find()

Open dgcampea opened this issue 4 years ago • 3 comments

Originally reported at: https://github.com/SoongNoonien/mpdevil/issues/38

Using client.find("title", "<string here>") results in connection loss. Searching with mpc client works though.

mpd version: Music Player Daemon 0.22.9 (0.22.9) python-mpd2 version: 3.0.4

Code sample:

>>> from mpd import MPDClient
>>> client = MPDClient()
>>> client.connect("localhost", 6600)
>>> client.find("title", "spend winter")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 469, in mpd_command
    return wrapper(self, name, args, callback)
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 532, in _execute
    return retval()
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 457, in command_callback
    res = self._wrap_iterator(res)
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 706, in _wrap_iterator
    return list(iterator)
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 240, in _parse_objects
    for key, value in self._parse_pairs(lines):
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 235, in _parse_pairs
    for line in lines:
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 586, in _read_lines
    line = self._read_line()
  File "/app/lib/python3.8/site-packages/mpd/base.py", line 571, in _read_line
    raise ConnectionError("Connection lost while reading line")
mpd.base.ConnectionError: Connection lost while reading line

dgcampea avatar Jul 22 '21 11:07 dgcampea

Notes:

  • mpc search title "a" works and returns results but python-mpd2 search("title", "a") loses connection, with mpd logs stating:
    exception: error on client 23: Output buffer is full
    
    python traceback:
    client.search("title", "a")
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 469, in mpd_command
          return wrapper(self, name, args, callback)
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 532, in _execute
          return retval()
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 457, in command_callback
          res = self._wrap_iterator(res)
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 706, in _wrap_iterator
          return list(iterator)
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 240, in _parse_objects
          for key, value in self._parse_pairs(lines):
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 235, in _parse_pairs
          for line in lines:
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 586, in _read_lines
          line = self._read_line()
      File "/app/lib/python3.8/site-packages/mpd/base.py", line 571, in _read_line
          raise ConnectionError("Connection lost while reading line")
      mpd.base.ConnectionError: Connection lost while reading line
    
  • Both mpc search title "spend winter" and python-mpd2 search("title", "spend winter") work and return results
  • mpc find title "a" and mpc find title "spend winter" works but returns no results, with exitcode 0. python-mpd2 find("title", "a") and python-mpd2 find("title", "spend winter") loses connection, with no output in mpd logs.

dgcampea avatar Jul 22 '21 12:07 dgcampea

tcpdump output might be helpful here of both mpc and python-mpd.

Mic92 avatar Jul 23 '21 08:07 Mic92

While investigating this, I think python-mpd find("title", "<string here>") is losing connection because it's parsing an empty mpd response and raising an exception. As a test:

$ nc localhost 6600
OK MPD 0.22.4
find title spend winter
OK

mpc search and python-mpd2 search() commands work, the reason mpc doesn't trigger "output buffer full" is because starting from libmpdclient 2.12 and mpd 2.12, mpc requests that mpd report the results with no tags at all. It's not in the documentation but python-mpd tagtypes() does accept arguments and maps them to the MPD protocol tagtypes, so to emulate mpc behavior, MPDClient.tagtypes("clear") should be done before searching and MPDClient.tagtypes("all") after the search is complete to return to the default tagtype state. I don't think this in particular is a python-mpd2 bug but it might be worth mentioning in the docs.

dgcampea avatar Jul 23 '21 11:07 dgcampea