Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhandled StopIteration exception #36

Closed
jcass77 opened this issue Dec 10, 2015 · 8 comments
Closed

Unhandled StopIteration exception #36

jcass77 opened this issue Dec 10, 2015 · 8 comments

Comments

@jcass77
Copy link
Contributor

jcass77 commented Dec 10, 2015

A StopIteration exception can occur on rare occasions when retrieving the next Pandora track.

Stack track details below:

  Received WebSocket message from 127.0.0.1: u'{"method":"core.library.browse","params":["pandora:station:2932455179979957924:2932455179979957924"],"jsonrpc":"2.0","id":1479}'
DEBUG    2015-12-10 10:17:04,778 [31248:PandoraBackend-14] pykka
  Exception returned from PandoraBackend (urn:uuid:e53806cb-71bd-4cf8-b1b8-6f97bc64c7fe) to caller:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 201, in _actor_loop
    response = self._handle_receive(message)
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 295, in _handle_receive
    return callee(*message['args'], **message['kwargs'])
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 46, in browse
    return self._browse_tracks(uri)
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 109, in _browse_tracks
    return [self.get_next_pandora_track()]
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 138, in get_next_pandora_track
    pandora_track = self._station_iter.next()
StopIteration
ERROR    2015-12-10 10:17:04,783 [31248:Core-16] mopidy.core.library
  PandoraBackend backend caused an exception.
Traceback (most recent call last):
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy/mopidy/core/library.py", line 19, in _backend_error_handling
    yield
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy/mopidy/core/library.py", line 112, in _browse
    result = backend.library.browse(uri).get()
  File "/usr/local/lib/python2.7/site-packages/pykka/threading.py", line 52, in get
    compat.reraise(*self._data['exc_info'])
  File "/usr/local/lib/python2.7/site-packages/pykka/compat.py", line 12, in reraise
    exec('raise tp, value, tb')
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 201, in _actor_loop
    response = self._handle_receive(message)
  File "/usr/local/lib/python2.7/site-packages/pykka/actor.py", line 295, in _handle_receive
    return callee(*message['args'], **message['kwargs'])
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 46, in browse
    return self._browse_tracks(uri)
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 109, in _browse_tracks
    return [self.get_next_pandora_track()]
  File "/Users/jcass/PycharmProjects/Mopidy/mopidy-pandora/mopidy_pandora/library.py", line 138, in get_next_pandora_track
    pandora_track = self._station_iter.next()
StopIteration
DEBUG    2015-12-10 10:17:10,338 [31248:HttpServer] mopidy.http.handlers
  Sent WebSocket message to 127.0.0.1: '{"jsonrpc": "2.0", "id": 1479, "result": []}'

This is supposed to be handled by stop_iteration, so not sure what the root cause is.

@jcass77
Copy link
Contributor Author

jcass77 commented Dec 13, 2015

@mcrute, I actually meant to log this issue in the Mopidy-Pandora project (too many browser tabs open) - which is why the stack trace references that code base.

...but I'm also uncertain as to what may cause this error as it looked to me like iterate_forever would handle all StopIteration exceptions? Any ideas?

@mcrute
Copy link
Owner

mcrute commented Dec 13, 2015

I tried to reproduce this but haven't had much luck, do you know what conditions this happens under? I tried a fake test and the only way I was able to reproduce the issues was if the wrapped function throws a StopIteration error when iterate_forever tries to refresh it's internal iterator. It would be possible to catch StopIteration a second time when refreshing the iterator but I'd like to reproduce this to find the root cause first.

Your Mopidy-Pandora code looks correct as far as I can tell.

@jcass77
Copy link
Contributor Author

jcass77 commented Dec 14, 2015

I noticed that the exception is also handled in

pydora/pydora/mpg123.py

Lines 96 to 100 in 264130b

try:
self.play(song)
except StopIteration:
self.stop()
return
- so perhaps you encountered this a long time ago?

When listening to some obscure artist using the iPhone or browser player, it has happened to me that Pandora would display a message saying that it does not have any more tracks for that station, and redirect to the main screen.

Perhaps it is possible that the array returned by get_playlist(station_token) can be empty for such situations?

From looking at https://github.com/PromyLOPh/pianobar/blob/7235a62c183d3815a0fc3dd7e05c6a3492a23f1f/src/libpiano/response.c#L87-L117 and https://github.com/PromyLOPh/pianobar/blob/7235a62c183d3815a0fc3dd7e05c6a3492a23f1f/src/libpiano/response.c#L223-L265 it seems that pianobar has a whole bunch of additional safeguards to check for null values, perhaps just for situations such as this?

@mcrute
Copy link
Owner

mcrute commented Dec 14, 2015

In my fake test I did try to return an empty list and None. Empty list causes iterate_forever to just call the function again and None causes an error about NoneType not being iterable. I'll see if I can reproduce it using an obscure artist (any recommendations?) to try debugging it a little more and build a fix.

I don't remember why I added the retry to the mpg123 player, it may well have been to fix this issue.

@jcass77
Copy link
Contributor Author

jcass77 commented Dec 14, 2015

Another difference may be that pydora uses iterate_forever in a for loop while Mopidy-Pandora calls next() on the generator. The first handles StopIteration implicitly while the approach that I am using doesn't: http://stackoverflow.com/questions/14413969/why-does-next-raise-a-stopiteration-but-for-do-a-normal-return

Either way, won't it make more sense for pydora to raise its own custom exception when no more tracks are being returned by get_playlist(station_token)?

I'm away from my keyboard for a short break so just speculating, and unfortunately not in a position to actually test this hypothesis.

@jcass77
Copy link
Contributor Author

jcass77 commented Dec 21, 2015

I think pep0479 might contain some additional background on the type of issue encountered here.

@mcrute
Copy link
Owner

mcrute commented Oct 8, 2016

@jcass77 it looks like you've taken a somewhat different approach to iterating the station list in mopidy-pandora. Given that and the fact that I'm still not able to reproduce the issue I'm going to close this issue. If this is still causing you problems feel free to re-open and I'll dig deeper into reproducing the error.

@mcrute mcrute closed this as completed Oct 8, 2016
@jcass77
Copy link
Contributor Author

jcass77 commented Oct 13, 2016

I am comfortable to close this as the solution that I am using has been stable for many months now.

I think the only point of discussion was whether it would make more sense for pydora to raise its own custom exception when no more tracks are being returned by get_playlist(station_token), instead of relying on StopIteration?

But it is such a minor detail that we can probably leave it as is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants