sigma67 / ytmusicapi

Unofficial API for YouTube Music
https://ytmusicapi.readthedocs.io
MIT License
1.71k stars 194 forks source link

KeyError 'runs' on get_library_playlists() #539

Closed linsomniac closed 7 months ago

linsomniac commented 7 months ago

Describe the bug I have a user over in https://github.com/linsomniac/spotify_to_ytmusic/issues/31 that is reporting the following traceback:

Traceback (most recent call last):
  File "/usr/local/bin/s2yt_copy_all_playlists", line 8, in <module>
    sys.exit(copy_all_playlists())
  File "/usr/local/lib/python3.10/site-packages/spotify2ytmusic/cli.py", line 264, in copy_all_playlists
    backend.copy_all_playlists(
  File "/usr/local/lib/python3.10/site-packages/spotify2ytmusic/backend.py", line 441, in copy_all_playlists
    dst_pl_id = get_playlist_id_by_name(yt, pl_name)
  File "/usr/local/lib/python3.10/site-packages/spotify2ytmusic/backend.py", line 163, in get_playlist_id_by_name
    for pl in yt.get_library_playlists(limit=5000):
  File "/usr/local/lib/python3.10/site-packages/ytmusicapi/mixins/library.py", line 35, in get_library_playlists
    playlists = parse_content_list(results["items"][1:], parse_playlist)
  File "/usr/local/lib/python3.10/site-packages/ytmusicapi/parsers/browsing.py", line 48, in parse_content_list
    contents.append(parse_func(result[key]))
  File "/usr/local/lib/python3.10/site-packages/ytmusicapi/parsers/browsing.py", line 126, in parse_playlist
    "title": nav(data, TITLE_TEXT),
  File "/usr/local/lib/python3.10/site-packages/ytmusicapi/navigation.py", line 103, in nav
    raise err
  File "/usr/local/lib/python3.10/site-packages/ytmusicapi/navigation.py", line 97, in nav
    root = root[k]
KeyError: 'runs'

It looks like this comes from "ytmusicapi/parsers/browsing.py" in line 126, which reads: "title": nav(data, TITLE_TEXT),, and "TITLE_TEXT" appears to be ["title", "runs", 0, "text"]. The record it is on apparently does not have a "runs" key. Perhaps that call to "nav()" should have the "none_if_absent=True" argument set?

I don't really understand the code in question so I'm reluctant to suggest a fix, especially as I don't have direct access to the data that is triggering this issue (it's reported by a user of my software, issue linked above).

To Reproduce It seems to largely be dependent on the users ytmusic environment, as I am not able to reproduce this.

Additional context None.

sigma67 commented 7 months ago

Can't fix without a reproduction. At least provide a screenshot of the library (record) in question?

linsomniac commented 7 months ago

I've create PR #540 which detects this problem and outputs some debugging information in this situation. I also removed the "catch Exception" which seemed like it was really just meant to catch KeyError, but the revised code will detect the missing key and directly return None.

sigma67 commented 7 months ago

I fail to see how the PR addresses the issue. It would be good to know what the invalid record looks like that is causing the bug

linsomniac commented 7 months ago

This PR addresses this issue because this issue has demonstrated a "blind spot in the code": a place where an error occurs but that there is insufficient information to diagnose. Unfortunately, not all users have the ability to hook up a debugger and get that information to us. I tried monkey-patching the nav() function in my code, but it didn't "take".

The user who reported this issue has worked around the problem by deleting a playlist they had with no songs in it, so I'm afraid we've lost the ability to reproduce this. I tried to reproduce it by creating some empty playlists based on their descriptions, but I was unable to reproduce it.

I'd recommend you consider the changes in the PR, so that future occurrences of this will provide the information that is needed for resolution or reproduction, plus the "catch Exception" way of capturing "item not in dict" has some issues (over-broad exception, try/catch performance).

sigma67 commented 7 months ago

Your argument has merit, I had a look