From 89bc0403e5d6e0c0a597a3c6b8384db8f301dc2d Mon Sep 17 00:00:00 2001 From: npeter83 Date: Fri, 19 Jun 2026 04:27:22 +0200 Subject: [PATCH 1/2] fix(api): surface YouTube action failures as 422, not 502 Same fix as the subscribe reconcile, applied to the remaining endpoints that wrapped a YouTubeError in a 502: video lookup (feed) and playlist refresh, push-plan, sync, and delete. A 502 is treated by the client as a transient "connection lost" blip, so a real, explainable YouTube failure showed the wrong message. 422 carries the clear detail to the error dialog instead. --- backend/app/routes/feed.py | 2 +- backend/app/routes/playlists.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/app/routes/feed.py b/backend/app/routes/feed.py index 8afa915..fb24597 100644 --- a/backend/app/routes/feed.py +++ b/backend/app/routes/feed.py @@ -552,7 +552,7 @@ def get_video_detail( with quota.attribute(user.id, "video_lookup"), YouTubeClient(db, user) as yt: items = yt.get_videos([video_id]) except YouTubeError as exc: - raise HTTPException(status_code=502, detail=f"YouTube lookup failed: {exc}") + raise HTTPException(status_code=422, detail=f"YouTube lookup failed: {exc}") if not items: raise HTTPException(status_code=404, detail="Unknown video") diff --git a/backend/app/routes/playlists.py b/backend/app/routes/playlists.py index b923161..741b2ca 100644 --- a/backend/app/routes/playlists.py +++ b/backend/app/routes/playlists.py @@ -270,7 +270,7 @@ def revert_youtube( return repull_playlist(db, user, pl) except YouTubeError: db.rollback() - raise HTTPException(status_code=502, detail="Couldn't refresh from YouTube.") + raise HTTPException(status_code=422, detail="Couldn't refresh from YouTube.") def _pushable(db: Session, user: User, playlist_id: int) -> Playlist: @@ -301,7 +301,7 @@ def push_plan( with quota.attribute(user.id, "playlist_push"): plan = plan_push(db, user, pl) except YouTubeError: - raise HTTPException(status_code=502, detail="Couldn't read the playlist on YouTube.") + raise HTTPException(status_code=422, detail="Couldn't read the playlist on YouTube.") plan["remaining_today"] = quota.remaining_today(db) plan["affordable"] = plan["units_estimate"] <= plan["remaining_today"] return plan @@ -332,7 +332,7 @@ def push( return push_playlist(db, user, pl) except YouTubeError: db.rollback() - raise HTTPException(status_code=502, detail="YouTube playlist sync failed.") + raise HTTPException(status_code=422, detail="YouTube playlist sync failed.") @router.get("/{playlist_id}") @@ -422,7 +422,7 @@ def delete_playlist( with YouTubeClient(db, user) as yt: yt.delete_playlist(pl.yt_playlist_id) except YouTubeError: - raise HTTPException(status_code=502, detail="YouTube delete failed.") + raise HTTPException(status_code=422, detail="YouTube delete failed.") db.delete(pl) # items cascade db.commit() return {"deleted": playlist_id} From 526fa85b6c3ed134f3bf7bd6e98652279cd89e29 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Fri, 19 Jun 2026 04:27:22 +0200 Subject: [PATCH 2/2] release: 0.11.2 --- VERSION | 2 +- frontend/src/lib/releaseNotes.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/VERSION b/VERSION index af88ba8..bc859cb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.1 +0.11.2 diff --git a/frontend/src/lib/releaseNotes.ts b/frontend/src/lib/releaseNotes.ts index f67de59..f9058d3 100644 --- a/frontend/src/lib/releaseNotes.ts +++ b/frontend/src/lib/releaseNotes.ts @@ -14,6 +14,14 @@ export interface ReleaseEntry { } export const RELEASE_NOTES: ReleaseEntry[] = [ + { + version: "0.11.2", + date: "2026-06-19", + summary: "Clearer messages when a YouTube action can't be completed.", + fixes: [ + "When a YouTube action can't go through — syncing or pushing a playlist, removing a playlist on YouTube, or looking up a video — you now get a clear explanation of why, instead of a misleading “connection lost” notice.", + ], + }, { version: "0.11.1", date: "2026-06-19",