fix(youtube): "this playlist no longer exists" only where the user picked that list

playlistNotFound was mapped to "gone" everywhere: exploring a channel without uploads (its
uploads list answers not found) and a list deleted mid bulk pull both said a playlist no
longer exists. The reason is now "gone" only on single-playlist routes; explore reads it
as an empty back-catalogue, and the bulk pull skips that list and syncs the rest.
This commit is contained in:
2026-10-04 04:16:52 +02:00
parent 4191189b4c
commit 79704b0001
7 changed files with 117 additions and 19 deletions
@@ -163,6 +163,33 @@ def test_a_playlist_answer_with_something_in_it_still_drops_a_vanished_mirror(
assert "PL1" not in ytids
class _YTOneGone(_YT):
"""A list deleted on YouTube between the listing and the read of its items."""
def iter_my_playlist_video_ids(self, ytid):
if ytid == "PLgone":
raise YouTubeError("m", reason="playlistNotFound", path="playlistItems")
return []
def test_a_list_deleted_mid_pull_is_skipped_and_the_rest_still_sync(db, make_user, monkeypatch):
# Not "this playlist no longer exists" for a bulk pull the user never named a list in, and not
# a failure for every other list either (E32 review round 2): the next pull drops the mirror.
user = make_user()
db.commit()
listing = [
{"id": "PLgone", "title": "Gone", "item_count": 3},
{"id": "PL2", "title": "Kept", "item_count": 0},
]
monkeypatch.setattr(plsync, "YouTubeClient", _YTOneGone(listing))
assert plsync.pull_user_playlists(db, user) == {"synced": 1}
db.expire_all()
ytids = set(
db.execute(select(Playlist.yt_playlist_id).where(Playlist.user_id == user.id)).scalars()
)
assert ytids == {"PL2"}
def _mirror_with_an_item(db, user, **kw):
db.add(Channel(id="UC_pl", title="C"))
db.flush()